From 6c37a89744149e68f198429fb7eac70fe1707360 Mon Sep 17 00:00:00 2001 From: Benjamin Bentmann Date: Tue, 24 Aug 2010 22:46:07 +0000 Subject: [PATCH] [MNG-4756] Aether integration git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@988749 13f79535-47bb-0310-9956-ffa450edef68 --- apache-maven/NOTICE.txt | 2 +- apache-maven/pom.xml | 4 + build.xml | 2 +- maven-aether-provider/pom.xml | 76 +++ .../DefaultArtifactDescriptorReader.java | 449 ++++++++++++++++ .../internal/DefaultModelCache.java | 119 +++++ .../internal/DefaultModelResolver.java | 128 +++++ .../internal/DefaultServiceLocator.java | 51 ++ .../internal/DefaultVersionRangeResolver.java | 269 ++++++++++ .../internal/DefaultVersionResolver.java | 487 ++++++++++++++++++ .../internal/LocalSnapshotMetadata.java | 102 ++++ .../LocalSnapshotMetadataGenerator.java | 76 +++ .../repository/internal/MavenMetadata.java | 171 ++++++ .../MavenRepositorySystemSession.java | 104 ++++ .../internal/RelocatedArtifact.java | 126 +++++ .../internal/RemoteSnapshotMetadata.java | 196 +++++++ .../RemoteSnapshotMetadataGenerator.java | 102 ++++ .../SnapshotMetadataGeneratorFactory.java | 52 ++ .../repository/internal/VersionsMetadata.java | 102 ++++ .../internal/VersionsMetadataGenerator.java | 99 ++++ .../VersionsMetadataGeneratorFactory.java | 52 ++ .../maven/artifact/DefaultArtifact.java | 1 - maven-compat/pom.xml | 6 + .../deployer/DefaultArtifactDeployer.java | 147 +++--- .../installer/DefaultArtifactInstaller.java | 121 +++-- .../DefaultRepositoryMetadataManager.java | 233 +-------- .../repository/metadata/MetadataBridge.java | 157 ++++++ .../resolver/DefaultArtifactResolver.java | 392 ++++---------- .../project/DefaultMavenProjectBuilder.java | 2 +- .../DefaultLegacyArtifactCollector.java | 1 - .../AbstractArtifactComponentTestCase.java | 61 ++- .../project/AbstractMavenProjectTestCase.java | 11 + .../project/ClasspathArtifactResolver.java | 82 +++ .../maven/project/EmptyLifecycleExecutor.java | 14 - .../project/EmptyLifecyclePluginAnalyzer.java | 78 +++ .../project/LegacyLocalRepositoryManager.java | 59 +++ .../maven/project/ProjectClasspathTest.java | 9 +- .../LegacyRepositorySystemTest.java | 12 + .../IdeWorkspaceRepositoryTest.java | 83 --- .../TestIdeWorkspaceRepository.java | 40 -- .../resolver/ArtifactResolverTest.xml | 21 +- .../project/AbstractMavenProjectTestCase.xml | 4 +- maven-core/pom.xml | 9 + .../apache/maven/ArtifactFilterManager.java | 7 +- .../maven/DefaultArtifactFilterManager.java | 26 +- .../java/org/apache/maven/DefaultMaven.java | 262 ++++++++-- .../DefaultProjectDependenciesResolver.java | 20 +- ...factRepository.java => ReactorReader.java} | 295 +++++------ .../org/apache/maven/RepositoryUtils.java | 325 ++++++++++++ .../handler/DefaultArtifactHandler.java | 21 + .../repository/DefaultRepositoryRequest.java | 37 +- .../artifact/repository/RepositoryCache.java | 1 + .../repository/RepositoryRequest.java | 32 -- .../resolver/ArtifactResolutionRequest.java | 22 +- .../ArtifactClassRealmConstituent.java | 8 +- .../maven/classrealm/ClassRealmManager.java | 2 +- .../classrealm/DefaultClassRealmManager.java | 27 +- .../DefaultMavenExecutionRequest.java | 15 +- .../DefaultMavenExecutionResult.java | 12 +- .../execution/MavenExecutionRequest.java | 8 +- .../maven/execution/MavenExecutionResult.java | 6 +- .../apache/maven/execution/MavenSession.java | 18 +- .../maven/lifecycle/DefaultSchedules.java | 10 - ...faultLifecycleExecutionPlanCalculator.java | 66 ++- .../internal/LifecycleDependencyResolver.java | 257 ++++++--- .../internal/LifecyclePluginResolver.java | 8 +- .../internal/MojoDescriptorCreator.java | 15 +- .../DefaultLifecycleBindingsInjector.java | 4 +- .../maven/plugin/BuildPluginManager.java | 38 +- .../org/apache/maven/plugin/CacheUtils.java | 211 ++++++++ .../plugin/DefaultBuildPluginManager.java | 54 +- .../plugin/DefaultExtensionRealmCache.java | 2 +- .../plugin/DefaultPluginArtifactsCache.java | 187 +++---- .../plugin/DefaultPluginDescriptorCache.java | 113 ++-- .../maven/plugin/DefaultPluginRealmCache.java | 201 +++----- .../maven/plugin/ExtensionRealmCache.java | 2 +- .../InvalidPluginDescriptorException.java | 2 - .../apache/maven/plugin/LegacySupport.java | 8 + .../maven/plugin/MavenPluginManager.java | 22 +- .../maven/plugin/PluginArtifactsCache.java | 23 +- .../maven/plugin/PluginDescriptorCache.java | 11 +- .../PluginDescriptorParsingException.java | 3 - .../PluginParameterExpressionEvaluator.java | 4 + .../apache/maven/plugin/PluginRealmCache.java | 30 +- .../plugin/PluginResolutionException.java | 13 +- .../plugin/internal/DefaultLegacySupport.java | 7 + .../internal/DefaultMavenPluginManager.java | 91 ++-- .../DefaultPluginDependenciesResolver.java | 205 ++++---- .../plugin/internal/DefaultPluginManager.java | 30 +- .../plugin/internal/PlexusUtilsInjector.java | 87 ++++ .../internal/PluginDependenciesResolver.java | 31 +- .../maven/plugin/internal/WagonExcluder.java | 109 ++++ .../prefix/DefaultPluginPrefixRequest.java | 125 ++--- .../NoPluginFoundForPrefixException.java | 22 +- .../plugin/prefix/PluginPrefixRequest.java | 72 +-- .../plugin/prefix/PluginPrefixResult.java | 4 +- .../internal/DefaultPluginPrefixResolver.java | 217 +++----- .../internal/DefaultPluginPrefixResult.java | 2 +- .../version/DefaultPluginVersionRequest.java | 141 ++--- .../plugin/version/PluginVersionRequest.java | 72 +-- .../PluginVersionResolutionException.java | 11 +- .../plugin/version/PluginVersionResult.java | 2 +- .../DefaultPluginVersionResolver.java | 208 ++++---- .../internal/DefaultPluginVersionResult.java | 2 +- .../DefaultDependencyResolutionRequest.java | 82 +++ .../DefaultDependencyResolutionResult.java | 111 ++++ .../project/DefaultModelBuildingListener.java | 2 +- .../maven/project/DefaultProjectBuilder.java | 150 +++--- .../project/DefaultProjectBuildingHelper.java | 66 +-- .../DefaultProjectBuildingRequest.java | 29 +- .../project/DefaultProjectBuildingResult.java | 14 +- .../DefaultProjectDependenciesResolver.java | 232 +++++++++ .../project/DefaultProjectRealmCache.java | 4 +- .../DependencyResolutionException.java} | 25 +- .../project/DependencyResolutionRequest.java | 79 +++ .../project/DependencyResolutionResult.java | 79 +++ .../apache/maven/project/MavenProject.java | 139 ++--- .../maven/project/ProjectBuildingRequest.java | 46 +- .../maven/project/ProjectBuildingResult.java | 3 +- .../project/ProjectDependenciesResolver.java | 40 ++ .../maven/project/ProjectRealmCache.java | 8 +- .../maven/project/ReactorModelResolver.java | 182 +++++++ .../project/RepositoryModelResolver.java | 189 ------- .../project/artifact/MavenMetadataSource.java | 37 +- .../artifact/ProjectArtifactMetadata.java | 5 + .../DelegatingLocalArtifactRepository.java | 2 +- .../DefaultMetadataResolutionRequest.java | 26 - .../metadata/MetadataResolutionRequest.java | 16 - .../AbstractCoreMavenComponentTestCase.java | 36 +- .../maven/MavenLifecycleParticipantTest.java | 2 +- .../EmptyLifecyclePluginAnalyzer.java | 77 +++ .../lifecycle/LifecycleExecutorTest.java | 13 +- .../internal/stub/BuildPluginManagerStub.java | 27 +- .../stub/PluginPrefixResolverStub.java | 2 +- .../stub/PluginVersionResolverStub.java | 2 +- .../stub/ProjectDependenciesResolverStub.java | 49 +- .../stub/ProjectDependencyGraphStub.java | 2 +- .../maven/plugin/PluginManagerTest.java | 41 +- .../project/AbstractMavenProjectTestCase.java | 11 + .../DefaultMavenProjectBuilderTest.java | 1 + .../maven/project/EmptyLifecycleExecutor.java | 16 - .../project/EmptyProjectBuildingHelper.java | 4 +- .../project/LegacyLocalRepositoryManager.java | 59 +++ .../maven/project/PomConstructionTest.java | 7 + .../repository/TestRepositoryConnector.java | 115 +++++ .../TestRepositoryConnectorFactory.java | 48 ++ .../PomConstructionWithSettingsTest.java | 7 + .../project/AbstractMavenProjectTestCase.xml | 4 +- .../maven/project/PomConstructionTest.xml | 4 +- .../cli/AbstractMavenTransferListener.java | 113 +--- .../cli/ConsoleMavenTransferListener.java | 37 +- .../java/org/apache/maven/cli/MavenCli.java | 7 +- .../maven/cli/QuietMavenTransferListener.java | 17 +- maven-repository-metadata/pom.xml | 2 +- .../src/main/mdo/metadata.mdo | 113 ++-- pom.xml | 49 +- 156 files changed, 7429 insertions(+), 3180 deletions(-) create mode 100644 maven-aether-provider/pom.xml create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultServiceLocator.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemSession.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java create mode 100644 maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java create mode 100644 maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java create mode 100644 maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java create mode 100644 maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java create mode 100644 maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java delete mode 100644 maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/IdeWorkspaceRepositoryTest.java delete mode 100644 maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/TestIdeWorkspaceRepository.java rename maven-core/src/main/java/org/apache/maven/{ReactorArtifactRepository.java => ReactorReader.java} (62%) create mode 100644 maven-core/src/main/java/org/apache/maven/RepositoryUtils.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java create mode 100644 maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java create mode 100644 maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java create mode 100644 maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java rename maven-core/src/main/java/org/apache/maven/{execution/SessionRepositoryCache.java => project/DependencyResolutionException.java} (56%) create mode 100644 maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java create mode 100644 maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java create mode 100644 maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java create mode 100644 maven-core/src/main/java/org/apache/maven/project/ReactorModelResolver.java delete mode 100644 maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java create mode 100644 maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java create mode 100644 maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java create mode 100644 maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java create mode 100644 maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java diff --git a/apache-maven/NOTICE.txt b/apache-maven/NOTICE.txt index c7a0185664..4675185cca 100644 --- a/apache-maven/NOTICE.txt +++ b/apache-maven/NOTICE.txt @@ -13,7 +13,7 @@ The Apache Software Foundation (http://www.apache.org/). This product includes software (Plexus and Classworlds) developed by The Codehaus Foundation (http://www.codehaus.org/). -This product includes software (Spice, Plexus Ciper and Sec Dispatcher) developed by +This product includes software (Aether, Spice, Plexus Ciper and Sec Dispatcher) developed by Sonatype Inc. (http://www.sonatype.org/). This product includes software (NekoHTML) developed by diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml index 24efbd782f..691873997d 100644 --- a/apache-maven/pom.xml +++ b/apache-maven/pom.xml @@ -59,6 +59,10 @@ org.apache.maven.wagon wagon-file + + org.sonatype.aether + aether-connector-wagon + diff --git a/build.xml b/build.xml index cc47ac917f..5dfbef63fe 100644 --- a/build.xml +++ b/build.xml @@ -195,7 +195,7 @@ Do you want to continue? - + diff --git a/maven-aether-provider/pom.xml b/maven-aether-provider/pom.xml new file mode 100644 index 0000000000..222495bb5c --- /dev/null +++ b/maven-aether-provider/pom.xml @@ -0,0 +1,76 @@ + + + + + + 4.0.0 + + + org.apache.maven + maven + 3.0-SNAPSHOT + + + maven-aether-provider + + Maven Aether Provider + + This module provides extensions to Aether for utilizing the Maven POM and Maven metadata. + + + + + org.apache.maven + maven-model-builder + + + org.apache.maven + maven-repository-metadata + + + org.sonatype.aether + aether-api + + + org.sonatype.aether + aether-util + + + org.sonatype.aether + aether-impl + + + org.codehaus.plexus + plexus-component-annotations + + + + + + + org.codehaus.plexus + plexus-component-metadata + + + + + diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java new file mode 100644 index 0000000000..bb73846ca8 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java @@ -0,0 +1,449 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.License; +import org.apache.maven.model.Model; +import org.apache.maven.model.Relocation; +import org.apache.maven.model.Repository; +import org.apache.maven.model.building.DefaultModelBuilderFactory; +import org.apache.maven.model.building.DefaultModelBuildingRequest; +import org.apache.maven.model.building.FileModelSource; +import org.apache.maven.model.building.ModelBuilder; +import org.apache.maven.model.building.ModelBuildingException; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblem; +import org.apache.maven.model.resolution.UnresolvableModelException; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.sonatype.aether.RepositoryException; +import org.sonatype.aether.RepositoryListener; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.artifact.ArtifactType; +import org.sonatype.aether.artifact.ArtifactTypeRegistry; +import org.sonatype.aether.graph.Dependency; +import org.sonatype.aether.graph.Exclusion; +import org.sonatype.aether.impl.ArtifactDescriptorReader; +import org.sonatype.aether.impl.ArtifactResolver; +import org.sonatype.aether.impl.RemoteRepositoryManager; +import org.sonatype.aether.impl.VersionResolver; +import org.sonatype.aether.transfer.ArtifactNotFoundException; +import org.sonatype.aether.util.artifact.ArtifactProperties; +import org.sonatype.aether.util.artifact.DefaultArtifact; +import org.sonatype.aether.util.artifact.DefaultArtifactType; +import org.sonatype.aether.util.artifact.SubArtifact; +import org.sonatype.aether.util.listener.DefaultRepositoryEvent; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.RepositoryPolicy; +import org.sonatype.aether.repository.WorkspaceRepository; +import org.sonatype.aether.resolution.ArtifactDescriptorException; +import org.sonatype.aether.resolution.ArtifactDescriptorRequest; +import org.sonatype.aether.resolution.ArtifactDescriptorResult; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.ArtifactResolutionException; +import org.sonatype.aether.resolution.ArtifactResult; +import org.sonatype.aether.resolution.VersionRequest; +import org.sonatype.aether.resolution.VersionResolutionException; +import org.sonatype.aether.spi.locator.Service; +import org.sonatype.aether.spi.locator.ServiceLocator; +import org.sonatype.aether.spi.log.Logger; +import org.sonatype.aether.spi.log.NullLogger; + +/** + * @author Benjamin Bentmann + */ +@Component( role = ArtifactDescriptorReader.class ) +public class DefaultArtifactDescriptorReader + implements ArtifactDescriptorReader, Service +{ + + @Requirement + private Logger logger = NullLogger.INSTANCE; + + @Requirement + private RemoteRepositoryManager remoteRepositoryManager; + + @Requirement + private VersionResolver versionResolver; + + @Requirement + private ArtifactResolver artifactResolver; + + @Requirement + private ModelBuilder modelBuilder; + + public void initService( ServiceLocator locator ) + { + setLogger( locator.getService( Logger.class ) ); + setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) ); + setVersionResolver( locator.getService( VersionResolver.class ) ); + setArtifactResolver( locator.getService( ArtifactResolver.class ) ); + modelBuilder = locator.getService( ModelBuilder.class ); + if ( modelBuilder == null ) + { + setModelBuilder( new DefaultModelBuilderFactory().newInstance() ); + } + } + + public DefaultArtifactDescriptorReader setLogger( Logger logger ) + { + this.logger = ( logger != null ) ? logger : NullLogger.INSTANCE; + return this; + } + + public DefaultArtifactDescriptorReader setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) + { + if ( remoteRepositoryManager == null ) + { + throw new IllegalArgumentException( "remote repository manager has not been specified" ); + } + this.remoteRepositoryManager = remoteRepositoryManager; + return this; + } + + public DefaultArtifactDescriptorReader setVersionResolver( VersionResolver versionResolver ) + { + if ( versionResolver == null ) + { + throw new IllegalArgumentException( "version resolver has not been specified" ); + } + this.versionResolver = versionResolver; + return this; + } + + public DefaultArtifactDescriptorReader setArtifactResolver( ArtifactResolver artifactResolver ) + { + if ( artifactResolver == null ) + { + throw new IllegalArgumentException( "artifact resolver has not been specified" ); + } + this.artifactResolver = artifactResolver; + return this; + } + + public DefaultArtifactDescriptorReader setModelBuilder( ModelBuilder modelBuilder ) + { + if ( modelBuilder == null ) + { + throw new IllegalArgumentException( "model builder has not been specified" ); + } + this.modelBuilder = modelBuilder; + return this; + } + + public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session, + ArtifactDescriptorRequest request ) + throws ArtifactDescriptorException + { + ArtifactDescriptorResult result = new ArtifactDescriptorResult( request ); + + Model model = loadPom( session, request, result ); + + if ( model != null ) + { + ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); + + for ( Repository r : model.getRepositories() ) + { + result.addRepository( convert( r ) ); + } + + for ( org.apache.maven.model.Dependency dependency : model.getDependencies() ) + { + result.addDependency( convert( dependency, stereotypes ) ); + } + + DependencyManagement mngt = model.getDependencyManagement(); + if ( mngt != null ) + { + for ( org.apache.maven.model.Dependency dependency : mngt.getDependencies() ) + { + result.addManagedDependency( convert( dependency, stereotypes ) ); + } + } + + Map properties = new LinkedHashMap(); + + List licenses = model.getLicenses(); + properties.put( "license.count", Integer.valueOf( licenses.size() ) ); + for ( int i = 0; i < licenses.size(); i++ ) + { + License license = licenses.get( i ); + properties.put( "license." + i + ".name", license.getName() ); + properties.put( "license." + i + ".url", license.getUrl() ); + properties.put( "license." + i + ".comments", license.getComments() ); + properties.put( "license." + i + ".distribution", license.getDistribution() ); + } + + result.setProperties( properties ); + } + + return result; + } + + private Model loadPom( RepositorySystemSession session, ArtifactDescriptorRequest request, + ArtifactDescriptorResult result ) + throws ArtifactDescriptorException + { + Set visited = new LinkedHashSet(); + for ( Artifact artifact = request.getArtifact();; ) + { + try + { + VersionRequest versionRequest = + new VersionRequest( artifact, request.getRepositories(), request.getRequestContext() ); + versionResolver.resolveVersion( session, versionRequest ); + } + catch ( VersionResolutionException e ) + { + result.addException( e ); + throw new ArtifactDescriptorException( result ); + } + + if ( !visited.add( artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion() ) ) + { + RepositoryException exception = + new RepositoryException( "Artifact relocations form a cycle: " + visited ); + invalidDescriptor( session, artifact, exception ); + if ( session.isIgnoreInvalidArtifactDescriptor() ) + { + return null; + } + result.addException( exception ); + throw new ArtifactDescriptorException( result ); + } + + Artifact pomArtifact = artifact; + if ( pomArtifact.getClassifier().length() > 0 || !"pom".equals( pomArtifact.getExtension() ) ) + { + pomArtifact = new SubArtifact( artifact, "", "pom" ); + } + + ArtifactResult resolveResult; + try + { + ArtifactRequest resolveRequest = + new ArtifactRequest( pomArtifact, request.getRepositories(), request.getRequestContext() ); + resolveResult = artifactResolver.resolveArtifact( session, resolveRequest ); + pomArtifact = resolveResult.getArtifact(); + result.setRepository( resolveResult.getRepository() ); + } + catch ( ArtifactResolutionException e ) + { + if ( e.getCause() instanceof ArtifactNotFoundException ) + { + missingDescriptor( session, artifact ); + if ( session.isIgnoreMissingArtifactDescriptor() ) + { + return null; + } + } + result.addException( e ); + throw new ArtifactDescriptorException( result ); + } + + Model model; + try + { + ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest(); + modelRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL ); + modelRequest.setProcessPlugins( false ); + modelRequest.setTwoPhaseBuilding( false ); + modelRequest.setSystemProperties( toProperties( session.getSystemProperties() ) ); + modelRequest.setUserProperties( toProperties( session.getUserProperties() ) ); + modelRequest.setModelCache( DefaultModelCache.newInstance( session ) ); + modelRequest.setModelResolver( new DefaultModelResolver( session, request.getRequestContext(), + artifactResolver, remoteRepositoryManager, + request.getRepositories() ) ); + if ( resolveResult.getRepository() instanceof WorkspaceRepository ) + { + modelRequest.setPomFile( pomArtifact.getFile() ); + } + else + { + modelRequest.setModelSource( new FileModelSource( pomArtifact.getFile() ) ); + } + + model = modelBuilder.build( modelRequest ).getEffectiveModel(); + } + catch ( ModelBuildingException e ) + { + for ( ModelProblem problem : e.getProblems() ) + { + if ( problem.getException() instanceof UnresolvableModelException ) + { + result.addException( problem.getException() ); + throw new ArtifactDescriptorException( result ); + } + } + invalidDescriptor( session, artifact, e ); + if ( session.isIgnoreInvalidArtifactDescriptor() ) + { + return null; + } + result.addException( e ); + throw new ArtifactDescriptorException( result ); + } + + Relocation relocation = getRelocation( model ); + + if ( relocation != null ) + { + result.addRelocation( artifact ); + artifact = + new RelocatedArtifact( artifact, relocation.getGroupId(), relocation.getArtifactId(), + relocation.getVersion() ); + result.setArtifact( artifact ); + } + else + { + return model; + } + } + } + + private Properties toProperties( Map map ) + { + Properties props = new Properties(); + if ( map != null ) + { + props.putAll( map ); + } + return props; + } + + private Relocation getRelocation( Model model ) + { + Relocation relocation = null; + DistributionManagement distMngt = model.getDistributionManagement(); + if ( distMngt != null ) + { + relocation = distMngt.getRelocation(); + } + return relocation; + } + + private Dependency convert( org.apache.maven.model.Dependency dependency, ArtifactTypeRegistry stereotypes ) + { + ArtifactType stereotype = stereotypes.get( dependency.getType() ); + if ( stereotype == null ) + { + stereotype = new DefaultArtifactType( dependency.getType() ); + } + + boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0; + + Map props = null; + if ( system ) + { + props = Collections.singletonMap( ArtifactProperties.LACKS_DESCRIPTOR, Boolean.TRUE.toString() ); + } + + Artifact artifact = + new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null, + dependency.getVersion(), props, stereotype ); + + if ( system ) + { + artifact = artifact.setFile( new File( dependency.getSystemPath() ) ); + } + + List exclusions = new ArrayList( dependency.getExclusions().size() ); + for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() ) + { + exclusions.add( convert( exclusion ) ); + } + + Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions ); + + return result; + } + + private Exclusion convert( org.apache.maven.model.Exclusion exclusion ) + { + return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" ); + } + + static RemoteRepository convert( Repository repository ) + { + RemoteRepository result = + new RemoteRepository( repository.getId(), repository.getLayout(), repository.getUrl() ); + result.setPolicy( true, convert( repository.getSnapshots() ) ); + result.setPolicy( false, convert( repository.getReleases() ) ); + return result; + } + + private static RepositoryPolicy convert( org.apache.maven.model.RepositoryPolicy policy ) + { + boolean enabled = true; + String checksums = RepositoryPolicy.CHECKSUM_POLICY_WARN; + String updates = RepositoryPolicy.UPDATE_POLICY_DAILY; + + if ( policy != null ) + { + enabled = policy.isEnabled(); + if ( policy.getUpdatePolicy() != null ) + { + updates = policy.getUpdatePolicy(); + } + if ( policy.getChecksumPolicy() != null ) + { + checksums = policy.getChecksumPolicy(); + } + } + + return new RepositoryPolicy( enabled, updates, checksums ); + } + + private void missingDescriptor( RepositorySystemSession session, Artifact artifact ) + { + RepositoryListener listener = session.getRepositoryListener(); + if ( listener != null ) + { + DefaultRepositoryEvent event = new DefaultRepositoryEvent( session, artifact ); + listener.artifactDescriptorMissing( event ); + } + } + + private void invalidDescriptor( RepositorySystemSession session, Artifact artifact, Exception exception ) + { + RepositoryListener listener = session.getRepositoryListener(); + if ( listener != null ) + { + DefaultRepositoryEvent event = new DefaultRepositoryEvent( session, artifact ); + event.setException( exception ); + listener.artifactDescriptorInvalid( event ); + } + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java new file mode 100644 index 0000000000..25b24c2c3f --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java @@ -0,0 +1,119 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import org.apache.maven.model.building.ModelCache; +import org.sonatype.aether.RepositoryCache; +import org.sonatype.aether.RepositorySystemSession; + +/** + * A model builder cache backed by the repository system cache. + * + * @author Benjamin Bentmann + */ +class DefaultModelCache + implements ModelCache +{ + + private final RepositorySystemSession session; + + private final RepositoryCache cache; + + public static ModelCache newInstance( RepositorySystemSession session ) + { + if ( session.getCache() == null ) + { + return null; + } + else + { + return new DefaultModelCache( session ); + } + } + + private DefaultModelCache( RepositorySystemSession session ) + { + this.session = session; + this.cache = session.getCache(); + } + + public Object get( String groupId, String artifactId, String version, String tag ) + { + return cache.get( session, new Key( groupId, artifactId, version, tag ) ); + } + + public void put( String groupId, String artifactId, String version, String tag, Object data ) + { + cache.put( session, new Key( groupId, artifactId, version, tag ), data ); + } + + static class Key + { + + private final String groupId; + + private final String artifactId; + + private final String version; + + private final String tag; + + private final int hash; + + public Key( String groupId, String artifactId, String version, String tag ) + { + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + this.tag = tag; + + int h = 17; + h = h * 31 + this.groupId.hashCode(); + h = h * 31 + this.artifactId.hashCode(); + h = h * 31 + this.version.hashCode(); + h = h * 31 + this.tag.hashCode(); + hash = h; + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + if ( null == obj || !getClass().equals( obj.getClass() ) ) + { + return false; + } + + Key that = (Key) obj; + return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId ) + && version.equals( that.version ) && tag.equals( that.tag ); + } + + @Override + public int hashCode() + { + return hash; + } + + } +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java new file mode 100644 index 0000000000..e9138bb93a --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java @@ -0,0 +1,128 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.maven.model.Repository; +import org.apache.maven.model.building.FileModelSource; +import org.apache.maven.model.building.ModelSource; +import org.apache.maven.model.resolution.InvalidRepositoryException; +import org.apache.maven.model.resolution.ModelResolver; +import org.apache.maven.model.resolution.UnresolvableModelException; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.impl.ArtifactResolver; +import org.sonatype.aether.impl.RemoteRepositoryManager; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.ArtifactResolutionException; +import org.sonatype.aether.util.artifact.DefaultArtifact; + +/** + * A model resolver to assist building of dependency POMs. This resolver gives priority to those repositories that have + * been initially specified and repositories discovered in dependency POMs are recessively merged into the search chain. + * + * @author Benjamin Bentmann + * @see DefaultArtifactDescriptorReader + */ +class DefaultModelResolver + implements ModelResolver +{ + + private final RepositorySystemSession session; + + private final String context; + + private List repositories; + + private final ArtifactResolver resolver; + + private final RemoteRepositoryManager remoteRepositoryManager; + + private final Set repositoryIds; + + public DefaultModelResolver( RepositorySystemSession session, String context, ArtifactResolver resolver, + RemoteRepositoryManager remoteRepositoryManager, List repositories ) + { + this.session = session; + this.context = context; + this.resolver = resolver; + this.remoteRepositoryManager = remoteRepositoryManager; + this.repositories = repositories; + this.repositoryIds = new HashSet(); + } + + private DefaultModelResolver( DefaultModelResolver original ) + { + this.session = original.session; + this.context = original.context; + this.resolver = original.resolver; + this.remoteRepositoryManager = original.remoteRepositoryManager; + this.repositories = original.repositories; + this.repositoryIds = new HashSet( original.repositoryIds ); + } + + public void addRepository( Repository repository ) + throws InvalidRepositoryException + { + if ( !repositoryIds.add( repository.getId() ) ) + { + return; + } + + List newRepositories = + Collections.singletonList( DefaultArtifactDescriptorReader.convert( repository ) ); + + this.repositories = + remoteRepositoryManager.aggregateRepositories( session, repositories, newRepositories, true ); + } + + public ModelResolver newCopy() + { + return new DefaultModelResolver( this ); + } + + public ModelSource resolveModel( String groupId, String artifactId, String version ) + throws UnresolvableModelException + { + Artifact pomArtifact = new DefaultArtifact( groupId, artifactId, "", "pom", version ); + + try + { + ArtifactRequest request = new ArtifactRequest( pomArtifact, repositories, context ); + pomArtifact = resolver.resolveArtifact( session, request ).getArtifact(); + } + catch ( ArtifactResolutionException e ) + { + throw new UnresolvableModelException( "Failed to resolve POM for " + groupId + ":" + artifactId + ":" + + version + " due to " + e.getMessage(), groupId, artifactId, version, e ); + } + + File pomFile = pomArtifact.getFile(); + + return new FileModelSource( pomFile ); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultServiceLocator.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultServiceLocator.java new file mode 100644 index 0000000000..f598590567 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultServiceLocator.java @@ -0,0 +1,51 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import org.sonatype.aether.impl.ArtifactDescriptorReader; +import org.sonatype.aether.impl.MetadataGeneratorFactory; +import org.sonatype.aether.impl.VersionRangeResolver; +import org.sonatype.aether.impl.VersionResolver; + +/** + * A simple service locator that is already setup with all components from this library. To acquire a complete + * repository system, clients need to add some repository connectors for remote transfers. Note: This component + * is meant to assists those clients that employ the repository systems outside of an IoC container, Maven plugins + * should instead always use regular dependency injection to acquire the repository system. + * + * @author Benjamin Bentmann + */ +public class DefaultServiceLocator + extends org.sonatype.aether.impl.internal.DefaultServiceLocator +{ + + /** + * Creates a new service locator that already knows about all service implementations included this library. + */ + public DefaultServiceLocator() + { + addService( ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class ); + addService( VersionResolver.class, DefaultVersionResolver.class ); + addService( VersionRangeResolver.class, DefaultVersionRangeResolver.class ); + addService( MetadataGeneratorFactory.class, SnapshotMetadataGeneratorFactory.class ); + addService( MetadataGeneratorFactory.class, VersionsMetadataGeneratorFactory.class ); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java new file mode 100644 index 0000000000..a84bf7cc53 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java @@ -0,0 +1,269 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.util.IOUtil; +import org.sonatype.aether.RepositoryListener; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.util.listener.DefaultRepositoryEvent; +import org.sonatype.aether.util.metadata.DefaultMetadata; +import org.sonatype.aether.util.version.GenericVersionScheme; +import org.sonatype.aether.version.InvalidVersionSpecificationException; +import org.sonatype.aether.version.Version; +import org.sonatype.aether.version.VersionConstraint; +import org.sonatype.aether.version.VersionRange; +import org.sonatype.aether.version.VersionScheme; +import org.sonatype.aether.impl.MetadataResolver; +import org.sonatype.aether.impl.VersionRangeResolver; +import org.sonatype.aether.metadata.Metadata; +import org.sonatype.aether.repository.ArtifactRepository; +import org.sonatype.aether.repository.LocalRepositoryManager; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.WorkspaceReader; +import org.sonatype.aether.resolution.MetadataRequest; +import org.sonatype.aether.resolution.MetadataResult; +import org.sonatype.aether.resolution.VersionRangeRequest; +import org.sonatype.aether.resolution.VersionRangeResolutionException; +import org.sonatype.aether.resolution.VersionRangeResult; +import org.sonatype.aether.spi.locator.Service; +import org.sonatype.aether.spi.locator.ServiceLocator; +import org.sonatype.aether.spi.log.Logger; +import org.sonatype.aether.spi.log.NullLogger; + +/** + * @author Benjamin Bentmann + */ +@Component( role = VersionRangeResolver.class ) +public class DefaultVersionRangeResolver + implements VersionRangeResolver, Service +{ + + private static final String MAVEN_METADATA_XML = "maven-metadata.xml"; + + @Requirement + private Logger logger = NullLogger.INSTANCE; + + @Requirement + private MetadataResolver metadataResolver; + + public void initService( ServiceLocator locator ) + { + setLogger( locator.getService( Logger.class ) ); + setMetadataResolver( locator.getService( MetadataResolver.class ) ); + } + + public DefaultVersionRangeResolver setLogger( Logger logger ) + { + this.logger = ( logger != null ) ? logger : NullLogger.INSTANCE; + return this; + } + + public DefaultVersionRangeResolver setMetadataResolver( MetadataResolver metadataResolver ) + { + if ( metadataResolver == null ) + { + throw new IllegalArgumentException( "metadata resolver has not been specified" ); + } + this.metadataResolver = metadataResolver; + return this; + } + + public VersionRangeResult resolveVersionRange( RepositorySystemSession session, VersionRangeRequest request ) + throws VersionRangeResolutionException + { + VersionRangeResult result = new VersionRangeResult( request ); + + VersionScheme versionScheme = new GenericVersionScheme(); + + VersionConstraint versionConstraint; + try + { + versionConstraint = versionScheme.parseVersionConstraint( request.getArtifact().getVersion() ); + } + catch ( InvalidVersionSpecificationException e ) + { + result.addException( e ); + throw new VersionRangeResolutionException( result ); + } + + result.setVersionConstraint( versionConstraint ); + + if ( versionConstraint.getRanges().isEmpty() ) + { + result.addVersion( versionConstraint.getVersion() ); + } + else + { + Map versionIndex = + getVersions( session, result, request, getNature( session, versionConstraint.getRanges() ) ); + + List versions = new ArrayList(); + for ( Map.Entry v : versionIndex.entrySet() ) + { + try + { + Version ver = versionScheme.parseVersion( v.getKey() ); + if ( versionConstraint.containsVersion( ver ) ) + { + versions.add( ver ); + result.setRepository( ver, v.getValue() ); + } + } + catch ( InvalidVersionSpecificationException e ) + { + result.addException( e ); + } + } + + Collections.sort( versions ); + result.setVersions( versions ); + } + + return result; + } + + private Map getVersions( RepositorySystemSession session, VersionRangeResult result, + VersionRangeRequest request, Metadata.Nature nature ) + { + Map versionIndex = new HashMap(); + + Metadata metadata = + new DefaultMetadata( request.getArtifact().getGroupId(), request.getArtifact().getArtifactId(), + MAVEN_METADATA_XML, nature ); + + List metadataRequests = new ArrayList( request.getRepositories().size() ); + for ( RemoteRepository repository : request.getRepositories() ) + { + MetadataRequest metadataRequest = new MetadataRequest( metadata, repository, request.getRequestContext() ); + metadataRequest.setDeleteLocalCopyIfMissing( true ); + metadataRequests.add( metadataRequest ); + } + List metadataResults = metadataResolver.resolveMetadata( session, metadataRequests ); + + WorkspaceReader workspace = session.getWorkspaceReader(); + if ( workspace != null ) + { + List versions = workspace.findVersions( request.getArtifact() ); + for ( String version : versions ) + { + versionIndex.put( version, workspace.getRepository() ); + } + } + + LocalRepositoryManager lrm = session.getLocalRepositoryManager(); + File localMetadataFile = new File( lrm.getRepository().getBasedir(), lrm.getPathForLocalMetadata( metadata ) ); + if ( localMetadataFile.isFile() ) + { + metadata = metadata.setFile( localMetadataFile ); + Versioning versioning = readVersions( session, metadata, result ); + for ( String version : versioning.getVersions() ) + { + if ( !versionIndex.containsKey( version ) ) + { + versionIndex.put( version, lrm.getRepository() ); + } + } + } + + for ( MetadataResult metadataResult : metadataResults ) + { + result.addException( metadataResult.getException() ); + Versioning versioning = readVersions( session, metadataResult.getMetadata(), result ); + for ( String version : versioning.getVersions() ) + { + if ( !versionIndex.containsKey( version ) ) + { + versionIndex.put( version, metadataResult.getRequest().getRepository() ); + } + } + } + + return versionIndex; + } + + private Metadata.Nature getNature( RepositorySystemSession session, Collection ranges ) + { + for ( VersionRange range : ranges ) + { + if ( range.acceptsSnapshots() ) + { + return Metadata.Nature.RELEASE_OR_SNAPSHOT; + } + } + return Metadata.Nature.RELEASE; + } + + private Versioning readVersions( RepositorySystemSession session, Metadata metadata, VersionRangeResult result ) + { + Versioning versioning = null; + + FileInputStream fis = null; + try + { + if ( metadata != null && metadata.getFile() != null ) + { + fis = new FileInputStream( metadata.getFile() ); + org.apache.maven.artifact.repository.metadata.Metadata m = new MetadataXpp3Reader().read( fis, false ); + versioning = m.getVersioning(); + } + } + catch ( FileNotFoundException e ) + { + // tolerable + } + catch ( Exception e ) + { + invalidMetadata( session, metadata, e ); + result.addException( e ); + } + finally + { + IOUtil.close( fis ); + } + + return ( versioning != null ) ? versioning : new Versioning(); + } + + private void invalidMetadata( RepositorySystemSession session, Metadata metadata, Exception exception ) + { + RepositoryListener listener = session.getRepositoryListener(); + if ( listener != null ) + { + DefaultRepositoryEvent event = new DefaultRepositoryEvent( session, metadata ); + event.setException( exception ); + listener.metadataInvalid( event ); + } + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java new file mode 100644 index 0000000000..684306040f --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java @@ -0,0 +1,487 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.maven.artifact.repository.metadata.Snapshot; +import org.apache.maven.artifact.repository.metadata.SnapshotVersion; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.StringUtils; +import org.sonatype.aether.RepositoryCache; +import org.sonatype.aether.RepositoryListener; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.util.listener.DefaultRepositoryEvent; +import org.sonatype.aether.util.metadata.DefaultMetadata; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.impl.MetadataResolver; +import org.sonatype.aether.impl.VersionResolver; +import org.sonatype.aether.impl.internal.CacheUtils; +import org.sonatype.aether.metadata.Metadata; +import org.sonatype.aether.repository.ArtifactRepository; +import org.sonatype.aether.repository.LocalRepositoryManager; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.WorkspaceReader; +import org.sonatype.aether.repository.WorkspaceRepository; +import org.sonatype.aether.resolution.MetadataRequest; +import org.sonatype.aether.resolution.MetadataResult; +import org.sonatype.aether.resolution.VersionRequest; +import org.sonatype.aether.resolution.VersionResolutionException; +import org.sonatype.aether.resolution.VersionResult; +import org.sonatype.aether.spi.locator.Service; +import org.sonatype.aether.spi.locator.ServiceLocator; +import org.sonatype.aether.spi.log.Logger; +import org.sonatype.aether.spi.log.NullLogger; + +/** + * @author Benjamin Bentmann + */ +@Component( role = VersionResolver.class ) +public class DefaultVersionResolver + implements VersionResolver, Service +{ + + private static final String MAVEN_METADATA_XML = "maven-metadata.xml"; + + private static final String RELEASE = "RELEASE"; + + private static final String LATEST = "LATEST"; + + private static final String SNAPSHOT = "SNAPSHOT"; + + @Requirement + private Logger logger = NullLogger.INSTANCE; + + @Requirement + private MetadataResolver metadataResolver; + + public void initService( ServiceLocator locator ) + { + setLogger( locator.getService( Logger.class ) ); + setMetadataResolver( locator.getService( MetadataResolver.class ) ); + } + + public DefaultVersionResolver setLogger( Logger logger ) + { + this.logger = ( logger != null ) ? logger : NullLogger.INSTANCE; + return this; + } + + public DefaultVersionResolver setMetadataResolver( MetadataResolver metadataResolver ) + { + if ( metadataResolver == null ) + { + throw new IllegalArgumentException( "metadata resolver has not been specified" ); + } + this.metadataResolver = metadataResolver; + return this; + } + + public VersionResult resolveVersion( RepositorySystemSession session, VersionRequest request ) + throws VersionResolutionException + { + Artifact artifact = request.getArtifact(); + + String version = artifact.getVersion(); + + VersionResult result = new VersionResult( request ); + + Key cacheKey = null; + RepositoryCache cache = session.getCache(); + if ( cache != null ) + { + cacheKey = new Key( session, request ); + + Object obj = cache.get( session, cacheKey ); + if ( obj instanceof Record ) + { + Record record = (Record) obj; + result.setVersion( record.version ); + result.setRepository( CacheUtils.getRepository( session, request.getRepositories(), record.repoClass, + record.repoId ) ); + return result; + } + } + + Metadata metadata; + + if ( RELEASE.equals( version ) ) + { + metadata = + new DefaultMetadata( artifact.getGroupId(), artifact.getArtifactId(), MAVEN_METADATA_XML, + Metadata.Nature.RELEASE ); + } + else if ( LATEST.equals( version ) ) + { + metadata = + new DefaultMetadata( artifact.getGroupId(), artifact.getArtifactId(), MAVEN_METADATA_XML, + Metadata.Nature.RELEASE_OR_SNAPSHOT ); + } + else if ( version.endsWith( SNAPSHOT ) ) + { + WorkspaceReader workspace = session.getWorkspaceReader(); + if ( workspace != null && workspace.findVersions( artifact ).contains( version ) ) + { + metadata = null; + result.setRepository( workspace.getRepository() ); + } + else + { + metadata = + new DefaultMetadata( artifact.getGroupId(), artifact.getArtifactId(), version, MAVEN_METADATA_XML, + Metadata.Nature.SNAPSHOT ); + } + } + else + { + metadata = null; + } + + if ( metadata == null ) + { + result.setVersion( version ); + } + else + { + List metadataRequests = new ArrayList( request.getRepositories().size() ); + for ( RemoteRepository repository : request.getRepositories() ) + { + MetadataRequest metadataRequest = + new MetadataRequest( metadata, repository, request.getRequestContext() ); + metadataRequest.setDeleteLocalCopyIfMissing( true ); + metadataRequest.setFavorLocalRepository( true ); + metadataRequests.add( metadataRequest ); + } + List metadataResults = metadataResolver.resolveMetadata( session, metadataRequests ); + + LocalRepositoryManager lrm = session.getLocalRepositoryManager(); + File localMetadataFile = + new File( lrm.getRepository().getBasedir(), lrm.getPathForLocalMetadata( metadata ) ); + if ( localMetadataFile.isFile() ) + { + metadata = metadata.setFile( localMetadataFile ); + } + + Map infos = new HashMap(); + merge( artifact, infos, readVersions( session, metadata, result ), + session.getLocalRepositoryManager().getRepository() ); + + for ( MetadataResult metadataResult : metadataResults ) + { + result.addException( metadataResult.getException() ); + merge( artifact, infos, readVersions( session, metadataResult.getMetadata(), result ), + metadataResult.getRequest().getRepository() ); + } + + if ( RELEASE.equals( version ) ) + { + resolve( result, infos, RELEASE ); + } + else if ( LATEST.equals( version ) ) + { + if ( !resolve( result, infos, LATEST ) ) + { + resolve( result, infos, RELEASE ); + } + + if ( result.getVersion() != null && result.getVersion().endsWith( SNAPSHOT ) ) + { + VersionRequest subRequest = new VersionRequest(); + subRequest.setArtifact( artifact.setVersion( result.getVersion() ) ); + if ( result.getRepository() instanceof RemoteRepository ) + { + subRequest.setRepositories( Collections.singletonList( (RemoteRepository) result.getRepository() ) ); + } + else + { + subRequest.setRepositories( request.getRepositories() ); + } + VersionResult subResult = resolveVersion( session, subRequest ); + result.setVersion( subResult.getVersion() ); + result.setRepository( subResult.getRepository() ); + for ( Exception exception : subResult.getExceptions() ) + { + result.addException( exception ); + } + } + } + else + { + if ( !resolve( result, infos, SNAPSHOT + artifact.getClassifier() ) + && !resolve( result, infos, SNAPSHOT ) ) + { + result.setVersion( version ); + } + } + + if ( StringUtils.isEmpty( result.getVersion() ) ) + { + throw new VersionResolutionException( result ); + } + } + + if ( cacheKey != null && metadata != null ) + { + cache.put( session, cacheKey, new Record( result.getVersion(), result.getRepository() ) ); + } + + return result; + } + + private boolean resolve( VersionResult result, Map infos, String key ) + { + VersionInfo info = infos.get( key ); + if ( info != null ) + { + result.setVersion( info.version ); + result.setRepository( info.repository ); + } + return info != null; + } + + private Versioning readVersions( RepositorySystemSession session, Metadata metadata, VersionResult result ) + { + Versioning versioning = null; + + FileInputStream fis = null; + try + { + if ( metadata != null && metadata.getFile() != null ) + { + fis = new FileInputStream( metadata.getFile() ); + org.apache.maven.artifact.repository.metadata.Metadata m = new MetadataXpp3Reader().read( fis, false ); + versioning = m.getVersioning(); + } + } + catch ( FileNotFoundException e ) + { + // tolerable + } + catch ( Exception e ) + { + invalidMetadata( session, metadata, e ); + result.addException( e ); + } + finally + { + IOUtil.close( fis ); + } + + return ( versioning != null ) ? versioning : new Versioning(); + } + + private void invalidMetadata( RepositorySystemSession session, Metadata metadata, Exception exception ) + { + RepositoryListener listener = session.getRepositoryListener(); + if ( listener != null ) + { + DefaultRepositoryEvent event = new DefaultRepositoryEvent( session, metadata ); + event.setException( exception ); + listener.metadataInvalid( event ); + } + } + + private void merge( Artifact artifact, Map infos, Versioning versioning, + ArtifactRepository repository ) + { + if ( StringUtils.isNotEmpty( versioning.getRelease() ) ) + { + merge( RELEASE, infos, versioning.getLastUpdated(), versioning.getRelease(), repository ); + } + + if ( StringUtils.isNotEmpty( versioning.getLatest() ) ) + { + merge( LATEST, infos, versioning.getLastUpdated(), versioning.getLatest(), repository ); + } + + boolean mainSnapshot = false; + for ( SnapshotVersion sv : versioning.getSnapshotVersions() ) + { + if ( StringUtils.isNotEmpty( sv.getVersion() ) ) + { + mainSnapshot |= sv.getClassifier().length() <= 0; + merge( SNAPSHOT + sv.getClassifier(), infos, sv.getUpdated(), sv.getVersion(), repository ); + } + } + + Snapshot snapshot = versioning.getSnapshot(); + if ( !mainSnapshot && snapshot != null ) + { + String version = artifact.getVersion(); + if ( snapshot.getTimestamp() != null && snapshot.getBuildNumber() > 0 ) + { + String qualifier = snapshot.getTimestamp() + '-' + snapshot.getBuildNumber(); + version = version.substring( 0, version.length() - SNAPSHOT.length() ) + qualifier; + } + merge( SNAPSHOT, infos, versioning.getLastUpdated(), version, repository ); + } + } + + private void merge( String key, Map infos, String timestamp, String version, + ArtifactRepository repository ) + { + VersionInfo info = infos.get( key ); + if ( info == null ) + { + info = new VersionInfo( timestamp, version, repository ); + infos.put( key, info ); + } + else if ( info.isOutdated( timestamp ) ) + { + info.version = version; + info.repository = repository; + } + } + + private static class VersionInfo + { + + String timestamp; + + String version; + + ArtifactRepository repository; + + public VersionInfo( String timestamp, String version, ArtifactRepository repository ) + { + this.timestamp = ( timestamp != null ) ? timestamp : ""; + this.version = version; + this.repository = repository; + } + + public boolean isOutdated( String timestamp ) + { + return timestamp != null && timestamp.compareTo( this.timestamp ) > 0; + } + + } + + private static class Key + { + + private final String groupId; + + private final String artifactId; + + private final String version; + + private final String context; + + private final File localRepo; + + private final WorkspaceRepository workspace; + + private final List repositories; + + private final int hashCode; + + public Key( RepositorySystemSession session, VersionRequest request ) + { + groupId = request.getArtifact().getGroupId(); + artifactId = request.getArtifact().getArtifactId(); + version = request.getArtifact().getVersion(); + context = request.getRequestContext(); + localRepo = session.getLocalRepository().getBasedir(); + workspace = CacheUtils.getWorkspace( session ); + repositories = new ArrayList( request.getRepositories().size() ); + for ( RemoteRepository repository : request.getRepositories() ) + { + if ( repository.isRepositoryManager() ) + { + repositories.addAll( repository.getMirroredRepositories() ); + } + else + { + repositories.add( repository ); + } + } + + int hash = 17; + hash = hash * 31 + groupId.hashCode(); + hash = hash * 31 + artifactId.hashCode(); + hash = hash * 31 + version.hashCode(); + hash = hash * 31 + localRepo.hashCode(); + hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories ); + hashCode = hash; + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == this ) + { + return true; + } + else if ( obj == null || !getClass().equals( obj.getClass() ) ) + { + return false; + } + + Key that = (Key) obj; + return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId ) + && version.equals( that.version ) && context.equals( that.context ) + && localRepo.equals( that.localRepo ) && CacheUtils.eq( workspace, that.workspace ) + && CacheUtils.repositoriesEquals( repositories, that.repositories ); + } + + @Override + public int hashCode() + { + return hashCode; + } + + } + + private static class Record + { + final String version; + + final String repoId; + + final Class repoClass; + + public Record( String version, ArtifactRepository repository ) + { + this.version = version; + if ( repository != null ) + { + repoId = repository.getId(); + repoClass = repository.getClass(); + } + else + { + repoId = null; + repoClass = null; + } + } + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java new file mode 100644 index 0000000000..7ad5ba2417 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java @@ -0,0 +1,102 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; + +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.artifact.repository.metadata.Snapshot; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.sonatype.aether.artifact.Artifact; + +/** + * @author Benjamin Bentmann + */ +final class LocalSnapshotMetadata + extends MavenMetadata +{ + + private final Artifact artifact; + + public LocalSnapshotMetadata( Artifact artifact ) + { + super( createMetadata( artifact ), null ); + this.artifact = artifact; + } + + public LocalSnapshotMetadata( Artifact artifact, File file ) + { + super( createMetadata( artifact ), file ); + this.artifact = artifact; + } + + private static Metadata createMetadata( Artifact artifact ) + { + Snapshot snapshot = new Snapshot(); + snapshot.setLocalCopy( true ); + Versioning versioning = new Versioning(); + versioning.setSnapshot( snapshot ); + + Metadata metadata = new Metadata(); + metadata.setModelVersion( "1.0.0" ); + metadata.setVersioning( versioning ); + metadata.setGroupId( artifact.getGroupId() ); + metadata.setArtifactId( artifact.getArtifactId() ); + metadata.setVersion( artifact.getBaseVersion() ); + + return metadata; + } + + public MavenMetadata setFile( File file ) + { + return new LocalSnapshotMetadata( artifact, file ); + } + + public Object getKey() + { + return getGroupId() + ':' + getArtifactId() + ':' + getVersion(); + } + + public static Object getKey( Artifact artifact ) + { + return artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion(); + } + + public String getGroupId() + { + return artifact.getGroupId(); + } + + public String getArtifactId() + { + return artifact.getArtifactId(); + } + + public String getVersion() + { + return artifact.getBaseVersion(); + } + + public Nature getNature() + { + return Nature.SNAPSHOT; + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java new file mode 100644 index 0000000000..8b234dd169 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java @@ -0,0 +1,76 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.impl.MetadataGenerator; +import org.sonatype.aether.installation.InstallRequest; +import org.sonatype.aether.metadata.Metadata; + +/** + * @author Benjamin Bentmann + */ +class LocalSnapshotMetadataGenerator + implements MetadataGenerator +{ + + private Map snapshots; + + public LocalSnapshotMetadataGenerator( RepositorySystemSession session, InstallRequest request ) + { + snapshots = new LinkedHashMap(); + } + + public Collection prepare( Collection artifacts ) + { + for ( Artifact artifact : artifacts ) + { + if ( artifact.isSnapshot() ) + { + Object key = LocalSnapshotMetadata.getKey( artifact ); + LocalSnapshotMetadata snapshotMetadata = snapshots.get( key ); + if ( snapshotMetadata == null ) + { + snapshotMetadata = new LocalSnapshotMetadata( artifact ); + snapshots.put( key, snapshotMetadata ); + } + } + } + + return Collections.emptyList(); + } + + public Artifact transformArtifact( Artifact artifact ) + { + return artifact; + } + + public Collection finish( Collection artifacts ) + { + return snapshots.values(); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java new file mode 100644 index 0000000000..2f924d4d49 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java @@ -0,0 +1,171 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; + +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; +import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.WriterFactory; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.sonatype.aether.RepositoryException; +import org.sonatype.aether.metadata.MergeableMetadata; + +/** + * @author Benjamin Bentmann + */ +abstract class MavenMetadata + implements MergeableMetadata +{ + + private final File file; + + protected Metadata metadata; + + private boolean merged; + + protected MavenMetadata( Metadata metadata, File file ) + { + this.metadata = metadata; + this.file = file; + } + + public String getType() + { + return "maven-metadata.xml"; + } + + public File getFile() + { + return file; + } + + public void merge( File existing, File result ) + throws RepositoryException + { + Metadata recessive = read( existing ); + + merge( recessive ); + + write( result, metadata ); + + merged = true; + } + + public boolean isMerged() + { + return merged; + } + + protected void merge( Metadata recessive ) + { + Versioning versioning = recessive.getVersioning(); + if ( versioning != null ) + { + versioning.setLastUpdated( null ); + } + + Metadata dominant = metadata; + + versioning = dominant.getVersioning(); + if ( versioning != null ) + { + versioning.updateTimestamp(); + } + + dominant.merge( recessive ); + } + + private Metadata read( File metadataFile ) + throws RepositoryException + { + if ( metadataFile.length() <= 0 ) + { + return new Metadata(); + } + + Reader reader = null; + try + { + reader = ReaderFactory.newXmlReader( metadataFile ); + return new MetadataXpp3Reader().read( reader, false ); + } + catch ( IOException e ) + { + throw new RepositoryException( "Could not read metadata " + metadataFile + ": " + e.getMessage(), e ); + } + catch ( XmlPullParserException e ) + { + throw new RepositoryException( "Could not parse metadata " + metadataFile + ": " + e.getMessage(), e ); + } + finally + { + IOUtil.close( reader ); + } + } + + private void write( File metadataFile, Metadata metadata ) + throws RepositoryException + { + Writer writer = null; + try + { + metadataFile.getParentFile().mkdirs(); + writer = WriterFactory.newXmlWriter( metadataFile ); + new MetadataXpp3Writer().write( writer, metadata ); + } + catch ( IOException e ) + { + throw new RepositoryException( "Could not write metadata " + metadataFile + ": " + e.getMessage(), e ); + } + finally + { + IOUtil.close( writer ); + } + } + + @Override + public String toString() + { + StringBuilder buffer = new StringBuilder( 128 ); + if ( getGroupId().length() > 0 ) + { + buffer.append( getGroupId() ); + } + if ( getArtifactId().length() > 0 ) + { + buffer.append( ':' ).append( getArtifactId() ); + } + if ( getVersion().length() > 0 ) + { + buffer.append( ':' ).append( getVersion() ); + } + buffer.append( '/' ).append( getType() ); + return buffer.toString(); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemSession.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemSession.java new file mode 100644 index 0000000000..a1fb8775c8 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemSession.java @@ -0,0 +1,104 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import org.sonatype.aether.collection.DependencyGraphTransformer; +import org.sonatype.aether.collection.DependencyManager; +import org.sonatype.aether.collection.DependencySelector; +import org.sonatype.aether.collection.DependencyTraverser; +import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.sonatype.aether.util.artifact.DefaultArtifactType; +import org.sonatype.aether.util.artifact.DefaultArtifactTypeRegistry; +import org.sonatype.aether.util.graph.manager.ClassicDependencyManager; +import org.sonatype.aether.util.graph.selector.AndDependencySelector; +import org.sonatype.aether.util.graph.selector.ExclusionDependencySelector; +import org.sonatype.aether.util.graph.selector.OptionalDependencySelector; +import org.sonatype.aether.util.graph.selector.ScopeDependencySelector; +import org.sonatype.aether.util.graph.transformer.ChainedDependencyGraphTransformer; +import org.sonatype.aether.util.graph.transformer.ConflictMarker; +import org.sonatype.aether.util.graph.transformer.JavaDependencyContextRefiner; +import org.sonatype.aether.util.graph.transformer.JavaEffectiveScopeCalculator; +import org.sonatype.aether.util.graph.transformer.NearestVersionConflictResolver; +import org.sonatype.aether.util.graph.traverser.FatArtifactTraverser; +import org.sonatype.aether.util.repository.DefaultAuthenticationSelector; +import org.sonatype.aether.util.repository.DefaultMirrorSelector; +import org.sonatype.aether.util.repository.DefaultProxySelector; + +/** + * A simplistic repository system session that mimics Maven's behavior to help third-party developers that want to embed + * Maven's dependency resolution into their own applications. Warning: This class is not intended for + * usage by Maven plugins, those should always acquire the current repository system session via parameter injection. + * + * @author Benjamin Bentmann + */ +public class MavenRepositorySystemSession + extends DefaultRepositorySystemSession +{ + + /** + * Creates a new Maven-like repository system session by initializing the session with values typical for + * Maven-based resolution. + */ + public MavenRepositorySystemSession() + { + setMirrorSelector( new DefaultMirrorSelector() ); + setAuthenticationSelector( new DefaultAuthenticationSelector() ); + setProxySelector( new DefaultProxySelector() ); + + DependencyTraverser depTraverser = new FatArtifactTraverser(); + setDependencyTraverser( depTraverser ); + + DependencyManager depManager = new ClassicDependencyManager(); + setDependencyManager( depManager ); + + DependencySelector depFilter = + new AndDependencySelector( new ScopeDependencySelector( "test", "provided" ), + new OptionalDependencySelector(), new ExclusionDependencySelector() ); + setDependencySelector( depFilter ); + + DependencyGraphTransformer transformer = + new ChainedDependencyGraphTransformer( new ConflictMarker(), new JavaEffectiveScopeCalculator(), + new NearestVersionConflictResolver(), + new JavaDependencyContextRefiner() ); + setDependencyGraphTransformer( transformer ); + + DefaultArtifactTypeRegistry stereotypes = new DefaultArtifactTypeRegistry(); + stereotypes.add( new DefaultArtifactType( "pom" ) ); + stereotypes.add( new DefaultArtifactType( "maven-plugin", "jar", "", "java" ) ); + stereotypes.add( new DefaultArtifactType( "jar", "jar", "", "java" ) ); + stereotypes.add( new DefaultArtifactType( "ejb", "jar", "", "java" ) ); + stereotypes.add( new DefaultArtifactType( "ejb-client", "jar", "client", "java" ) ); + stereotypes.add( new DefaultArtifactType( "test-jar", "jar", "tests", "java" ) ); + stereotypes.add( new DefaultArtifactType( "javadoc", "jar", "javadoc", "java" ) ); + stereotypes.add( new DefaultArtifactType( "java-source", "jar", "sources", "java", false, false ) ); + stereotypes.add( new DefaultArtifactType( "war", "war", "", "java", false, true ) ); + stereotypes.add( new DefaultArtifactType( "ear", "ear", "", "java", false, true ) ); + stereotypes.add( new DefaultArtifactType( "rar", "rar", "", "java", false, true ) ); + stereotypes.add( new DefaultArtifactType( "par", "par", "", "java", false, true ) ); + setArtifactTypeRegistry( stereotypes ); + + setIgnoreInvalidArtifactDescriptor( true ); + setIgnoreMissingArtifactDescriptor( true ); + + setSystemProps( System.getProperties() ); + setConfigProps( System.getProperties() ); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java new file mode 100644 index 0000000000..3acc3cb636 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java @@ -0,0 +1,126 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; +import java.util.Map; + +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.util.artifact.AbstractArtifact; + +/** + * @author Benjamin Bentmann + */ +final class RelocatedArtifact + extends AbstractArtifact +{ + + private final Artifact artifact; + + private final String groupId; + + private final String artifactId; + + private final String version; + + public RelocatedArtifact( Artifact artifact, String groupId, String artifactId, String version ) + { + if ( artifact == null ) + { + throw new IllegalArgumentException( "no artifact specified" ); + } + this.artifact = artifact; + this.groupId = ( groupId != null && groupId.length() > 0 ) ? groupId : null; + this.artifactId = ( artifactId != null && artifactId.length() > 0 ) ? artifactId : null; + this.version = ( version != null && version.length() > 0 ) ? version : null; + } + + public String getGroupId() + { + if ( groupId != null ) + { + return groupId; + } + else + { + return artifact.getGroupId(); + } + } + + public String getArtifactId() + { + if ( artifactId != null ) + { + return artifactId; + } + else + { + return artifact.getArtifactId(); + } + } + + public String getVersion() + { + if ( version != null ) + { + return version; + } + else + { + return artifact.getVersion(); + } + } + + public String getBaseVersion() + { + return toBaseVersion( getVersion() ); + } + + public boolean isSnapshot() + { + return isSnapshot( getVersion() ); + } + + public String getClassifier() + { + return artifact.getClassifier(); + } + + public String getExtension() + { + return artifact.getExtension(); + } + + public File getFile() + { + return artifact.getFile(); + } + + public String getProperty( String key, String defaultValue ) + { + return artifact.getProperty( key, defaultValue ); + } + + public Map getProperties() + { + return artifact.getProperties(); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java new file mode 100644 index 0000000000..6f1f1b47a5 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java @@ -0,0 +1,196 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.artifact.repository.metadata.Snapshot; +import org.apache.maven.artifact.repository.metadata.SnapshotVersion; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.sonatype.aether.artifact.Artifact; + +/** + * @author Benjamin Bentmann + */ +final class RemoteSnapshotMetadata + extends MavenMetadata +{ + + private static final String SNAPSHOT = "SNAPSHOT"; + + private final Collection artifacts = new ArrayList(); + + private final Map versions = new LinkedHashMap(); + + public RemoteSnapshotMetadata( Artifact artifact ) + { + super( createMetadata( artifact ), null ); + } + + private RemoteSnapshotMetadata( Metadata metadata, File file ) + { + super( metadata, file ); + } + + private static Metadata createMetadata( Artifact artifact ) + { + Metadata metadata = new Metadata(); + metadata.setModelVersion( "1.1.0" ); + metadata.setGroupId( artifact.getGroupId() ); + metadata.setArtifactId( artifact.getArtifactId() ); + metadata.setVersion( artifact.getBaseVersion() ); + + return metadata; + } + + public void bind( Artifact artifact ) + { + artifacts.add( artifact ); + } + + public MavenMetadata setFile( File file ) + { + return new RemoteSnapshotMetadata( metadata, file ); + } + + public Object getKey() + { + return getGroupId() + ':' + getArtifactId() + ':' + getVersion(); + } + + public static Object getKey( Artifact artifact ) + { + return artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion(); + } + + public String getExpandedVersion( Artifact artifact ) + { + return versions.get( artifact.getClassifier() ).getVersion(); + } + + @Override + protected void merge( Metadata recessive ) + { + Snapshot snapshot; + String lastUpdated = ""; + + if ( metadata.getVersioning() == null ) + { + DateFormat utcDateFormatter = new SimpleDateFormat( "yyyyMMdd.HHmmss" ); + utcDateFormatter.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); + + snapshot = new Snapshot(); + snapshot.setBuildNumber( getBuildNumber( recessive ) + 1 ); + snapshot.setTimestamp( utcDateFormatter.format( new Date() ) ); + + Versioning versioning = new Versioning(); + versioning.setSnapshot( snapshot ); + versioning.setLastUpdated( snapshot.getTimestamp().replace( ".", "" ) ); + lastUpdated = versioning.getLastUpdated(); + + metadata.setVersioning( versioning ); + } + else + { + snapshot = metadata.getVersioning().getSnapshot(); + lastUpdated = metadata.getVersioning().getLastUpdated(); + } + + for ( Artifact artifact : artifacts ) + { + String version = artifact.getVersion(); + + if ( version.endsWith( SNAPSHOT ) ) + { + String qualifier = snapshot.getTimestamp() + "-" + snapshot.getBuildNumber(); + version = version.substring( 0, version.length() - SNAPSHOT.length() ) + qualifier; + } + + SnapshotVersion sv = new SnapshotVersion(); + sv.setClassifier( artifact.getClassifier() ); + sv.setVersion( version ); + sv.setUpdated( lastUpdated ); + versions.put( sv.getClassifier(), sv ); + } + + artifacts.clear(); + + Versioning versioning = recessive.getVersioning(); + if ( versioning != null ) + { + for ( SnapshotVersion sv : versioning.getSnapshotVersions() ) + { + if ( !versions.containsKey( sv.getClassifier() ) ) + { + versions.put( sv.getClassifier(), sv ); + } + } + } + + metadata.getVersioning().setSnapshotVersions( new ArrayList( versions.values() ) ); + } + + private static int getBuildNumber( Metadata metadata ) + { + int number = 0; + + Versioning versioning = metadata.getVersioning(); + if ( versioning != null ) + { + Snapshot snapshot = versioning.getSnapshot(); + if ( snapshot != null && snapshot.getBuildNumber() > 0 ) + { + number = snapshot.getBuildNumber(); + } + } + + return number; + } + + public String getGroupId() + { + return metadata.getGroupId(); + } + + public String getArtifactId() + { + return metadata.getArtifactId(); + } + + public String getVersion() + { + return metadata.getVersion(); + } + + public Nature getNature() + { + return Nature.SNAPSHOT; + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java new file mode 100644 index 0000000000..d8a8525ed5 --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java @@ -0,0 +1,102 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.deployment.DeployRequest; +import org.sonatype.aether.impl.MetadataGenerator; +import org.sonatype.aether.metadata.Metadata; + +/** + * @author Benjamin Bentmann + */ +class RemoteSnapshotMetadataGenerator + implements MetadataGenerator +{ + + private Map snapshots; + + public RemoteSnapshotMetadataGenerator( RepositorySystemSession session, DeployRequest request ) + { + snapshots = new LinkedHashMap(); + + /* + * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which + * processes one artifact at a time and hence cannot associate the artifacts from the same project to use the + * same timestamp+buildno for the snapshot versions. Allowing the caller to pass in metadata from a previous + * deployment allows to re-establish the association between the artifacts of the same project. + */ + for ( Metadata metadata : request.getMetadata() ) + { + if ( metadata instanceof RemoteSnapshotMetadata ) + { + RemoteSnapshotMetadata snapshotMetadata = (RemoteSnapshotMetadata) metadata; + snapshots.put( snapshotMetadata.getKey(), snapshotMetadata ); + } + } + } + + public Collection prepare( Collection artifacts ) + { + for ( Artifact artifact : artifacts ) + { + if ( artifact.isSnapshot() ) + { + Object key = RemoteSnapshotMetadata.getKey( artifact ); + RemoteSnapshotMetadata snapshotMetadata = snapshots.get( key ); + if ( snapshotMetadata == null ) + { + snapshotMetadata = new RemoteSnapshotMetadata( artifact ); + snapshots.put( key, snapshotMetadata ); + } + snapshotMetadata.bind( artifact ); + } + } + + return snapshots.values(); + } + + public Artifact transformArtifact( Artifact artifact ) + { + if ( artifact.isSnapshot() && artifact.getVersion().equals( artifact.getBaseVersion() ) ) + { + Object key = RemoteSnapshotMetadata.getKey( artifact ); + RemoteSnapshotMetadata snapshotMetadata = snapshots.get( key ); + if ( snapshotMetadata != null ) + { + artifact = artifact.setVersion( snapshotMetadata.getExpandedVersion( artifact ) ); + } + } + + return artifact; + } + + public Collection finish( Collection artifacts ) + { + return Collections.emptyList(); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java new file mode 100644 index 0000000000..60e9c3e99c --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java @@ -0,0 +1,52 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.deployment.DeployRequest; +import org.sonatype.aether.impl.MetadataGenerator; +import org.sonatype.aether.impl.MetadataGeneratorFactory; +import org.sonatype.aether.installation.InstallRequest; + +/** + * @author Benjamin Bentmann + */ +@Component( role = MetadataGeneratorFactory.class, hint = "snapshot" ) +public class SnapshotMetadataGeneratorFactory + implements MetadataGeneratorFactory +{ + + public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request ) + { + return new LocalSnapshotMetadataGenerator( session, request ); + } + + public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request ) + { + return new RemoteSnapshotMetadataGenerator( session, request ); + } + + public int getPriority() + { + return 10; + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java new file mode 100644 index 0000000000..3008454c1c --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java @@ -0,0 +1,102 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.io.File; + +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.sonatype.aether.artifact.Artifact; + +/** + * @author Benjamin Bentmann + */ +final class VersionsMetadata + extends MavenMetadata +{ + + private final Artifact artifact; + + public VersionsMetadata( Artifact artifact ) + { + super( createMetadata( artifact ), null ); + this.artifact = artifact; + } + + public VersionsMetadata( Artifact artifact, File file ) + { + super( createMetadata( artifact ), file ); + this.artifact = artifact; + } + + private static Metadata createMetadata( Artifact artifact ) + { + Versioning versioning = new Versioning(); + versioning.addVersion( artifact.getBaseVersion() ); + if ( !artifact.isSnapshot() ) + { + versioning.setRelease( artifact.getVersion() ); + } + + Metadata metadata = new Metadata(); + metadata.setModelVersion( "1.0.0" ); + metadata.setVersioning( versioning ); + metadata.setGroupId( artifact.getGroupId() ); + metadata.setArtifactId( artifact.getArtifactId() ); + + return metadata; + } + + public Object getKey() + { + return getGroupId() + ':' + getArtifactId(); + } + + public static Object getKey( Artifact artifact ) + { + return artifact.getGroupId() + ':' + artifact.getArtifactId(); + } + + public MavenMetadata setFile( File file ) + { + return new VersionsMetadata( artifact, file ); + } + + public String getGroupId() + { + return artifact.getGroupId(); + } + + public String getArtifactId() + { + return artifact.getArtifactId(); + } + + public String getVersion() + { + return ""; + } + + public Nature getNature() + { + return artifact.isSnapshot() ? Nature.RELEASE_OR_SNAPSHOT : Nature.RELEASE; + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java new file mode 100644 index 0000000000..ed3d4c625f --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java @@ -0,0 +1,99 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.deployment.DeployRequest; +import org.sonatype.aether.impl.MetadataGenerator; +import org.sonatype.aether.installation.InstallRequest; +import org.sonatype.aether.metadata.Metadata; + +/** + * @author Benjamin Bentmann + */ +class VersionsMetadataGenerator + implements MetadataGenerator +{ + + private Map versions; + + public VersionsMetadataGenerator( RepositorySystemSession session, InstallRequest request ) + { + this( session, request.getMetadata() ); + } + + public VersionsMetadataGenerator( RepositorySystemSession session, DeployRequest request ) + { + this( session, request.getMetadata() ); + } + + private VersionsMetadataGenerator( RepositorySystemSession session, Collection metadatas ) + { + versions = new LinkedHashMap(); + + /* + * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which + * processes one artifact at a time and hence cannot associate the artifacts from the same project to use the + * same timestamp+buildno for the snapshot versions. Allowing the caller to pass in metadata from a previous + * deployment allows to re-establish the association between the artifacts of the same project. + */ + for ( Metadata metadata : metadatas ) + { + if ( metadata instanceof VersionsMetadata ) + { + VersionsMetadata versionsMetadata = (VersionsMetadata) metadata; + versions.put( versionsMetadata.getKey(), versionsMetadata ); + } + } + } + + public Collection prepare( Collection artifacts ) + { + return Collections.emptyList(); + } + + public Artifact transformArtifact( Artifact artifact ) + { + return artifact; + } + + public Collection finish( Collection artifacts ) + { + for ( Artifact artifact : artifacts ) + { + Object key = VersionsMetadata.getKey( artifact ); + VersionsMetadata versionsMetadata = versions.get( key ); + if ( versionsMetadata == null ) + { + versionsMetadata = new VersionsMetadata( artifact ); + versions.put( key, versionsMetadata ); + } + } + + return versions.values(); + } + +} diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java new file mode 100644 index 0000000000..a1e986f5ba --- /dev/null +++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java @@ -0,0 +1,52 @@ +package org.apache.maven.repository.internal; + +/* + * 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. + */ + +import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.deployment.DeployRequest; +import org.sonatype.aether.impl.MetadataGenerator; +import org.sonatype.aether.impl.MetadataGeneratorFactory; +import org.sonatype.aether.installation.InstallRequest; + +/** + * @author Benjamin Bentmann + */ +@Component( role = MetadataGeneratorFactory.class, hint = "versions" ) +public class VersionsMetadataGeneratorFactory + implements MetadataGeneratorFactory +{ + + public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request ) + { + return new VersionsMetadataGenerator( session, request ); + } + + public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request ) + { + return new VersionsMetadataGenerator( session, request ); + } + + public int getPriority() + { + return 5; + } + +} diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java index 8878b06e0e..ca588f9509 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java @@ -493,7 +493,6 @@ public VersionRange getVersionRange() public void setVersionRange( VersionRange versionRange ) { this.versionRange = versionRange; - selectVersionFromNewRangeIfAvailable(); } diff --git a/maven-compat/pom.xml b/maven-compat/pom.xml index 74d5590e56..2912053eb8 100644 --- a/maven-compat/pom.xml +++ b/maven-compat/pom.xml @@ -69,6 +69,12 @@ wagon-file test + + org.sonatype.aether + aether-connector-wagon + ${aetherVersion} + test + easymock easymock diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java b/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java index 34400afdda..4e5bfc6c63 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java @@ -20,50 +20,46 @@ */ import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.DefaultArtifactRepository; -import org.apache.maven.artifact.repository.metadata.RepositoryMetadataDeploymentException; -import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager; -import org.apache.maven.execution.MavenExecutionRequest; -import org.apache.maven.execution.MavenSession; +import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata; +import org.apache.maven.artifact.repository.metadata.MetadataBridge; +import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata; import org.apache.maven.plugin.LegacySupport; -import org.apache.maven.repository.RepositorySystem; -import org.apache.maven.repository.legacy.TransferListenerAdapter; -import org.apache.maven.repository.legacy.WagonManager; -import org.apache.maven.repository.legacy.resolver.transform.ArtifactTransformationManager; -import org.apache.maven.wagon.TransferFailedException; -import org.apache.maven.wagon.events.TransferListener; +import org.apache.maven.project.artifact.ProjectArtifactMetadata; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.codehaus.plexus.util.FileUtils; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.deployment.DeployRequest; +import org.sonatype.aether.deployment.DeployResult; +import org.sonatype.aether.deployment.DeploymentException; +import org.sonatype.aether.metadata.MergeableMetadata; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.sonatype.aether.util.artifact.SubArtifact; -@Component( role = ArtifactDeployer.class ) +@Component( role = ArtifactDeployer.class, instantiationStrategy = "per-lookup" ) public class DefaultArtifactDeployer extends AbstractLogEnabled implements ArtifactDeployer { - @Requirement - private WagonManager wagonManager; @Requirement - private ArtifactTransformationManager transformationManager; - - @Requirement - private RepositoryMetadataManager repositoryMetadataManager; - - @Requirement - private RepositorySystem repositorySystem; + private RepositorySystem repoSystem; @Requirement private LegacySupport legacySupport; + private Map snapshots = new ConcurrentHashMap(); + /** * @deprecated we want to use the artifact method only, and ensure artifact.file is set * correctly. @@ -82,79 +78,78 @@ public void deploy( File source, Artifact artifact, ArtifactRepository deploymen ArtifactRepository localRepository ) throws ArtifactDeploymentException { - deploymentRepository = injectSession( deploymentRepository ); + DefaultRepositorySystemSession session = + new DefaultRepositorySystemSession( legacySupport.getRepositorySession() ); + LocalRepository localRepo = new LocalRepository( localRepository.getBasedir() ); + session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( localRepo ) ); - try + DeployRequest request = new DeployRequest(); + + org.sonatype.aether.artifact.Artifact mainArtifact = RepositoryUtils.toArtifact( artifact ); + mainArtifact = mainArtifact.setFile( source ); + request.addArtifact( mainArtifact ); + + String snapshotKey = null; + if ( artifact.isSnapshot() ) { - transformationManager.transformForDeployment( artifact, deploymentRepository, localRepository ); + snapshotKey = artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion(); + request.addMetadata( snapshots.get( snapshotKey ) ); + } - // Copy the original file to the new one if it was transformed - File artifactFile = new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) ); - if ( !artifactFile.equals( source ) ) + for ( ArtifactMetadata metadata : artifact.getMetadataList() ) + { + if ( metadata instanceof ProjectArtifactMetadata ) { - FileUtils.copyFile( source, artifactFile ); + org.sonatype.aether.artifact.Artifact pomArtifact = new SubArtifact( mainArtifact, "", "pom" ); + pomArtifact = pomArtifact.setFile( ( (ProjectArtifactMetadata) metadata ).getFile() ); + request.addArtifact( pomArtifact ); } - - wagonManager.putArtifact( source, artifact, deploymentRepository, getTransferListener() ); - - // must be after the artifact is installed - for ( ArtifactMetadata metadata : artifact.getMetadataList() ) + else if ( metadata instanceof SnapshotArtifactRepositoryMetadata + || metadata instanceof ArtifactRepositoryMetadata ) { - repositoryMetadataManager.deploy( metadata, localRepository, deploymentRepository ); + // eaten, handled by repo system + } + else + { + request.addMetadata( new MetadataBridge( metadata ) ); } } - catch ( TransferFailedException e ) - { - throw new ArtifactDeploymentException( "Error deploying artifact: " + e.getMessage(), e ); - } - catch ( IOException e ) - { - throw new ArtifactDeploymentException( "Error deploying artifact: " + e.getMessage(), e ); - } - catch ( RepositoryMetadataDeploymentException e ) - { - throw new ArtifactDeploymentException( "Error installing artifact's metadata: " + e.getMessage(), e ); - } - } - private TransferListener getTransferListener() - { - MavenSession session = legacySupport.getSession(); - - if ( session == null ) - { - return null; - } - - return TransferListenerAdapter.newAdapter( session.getRequest().getTransferListener() ); - } - - private ArtifactRepository injectSession( ArtifactRepository repository ) - { + RemoteRepository remoteRepo = RepositoryUtils.toRepo( deploymentRepository ); /* * NOTE: This provides backward-compat with maven-deploy-plugin:2.4 which bypasses the repository factory when * using an alternative deployment location. */ - if ( repository instanceof DefaultArtifactRepository && repository.getAuthentication() == null ) + if ( deploymentRepository instanceof DefaultArtifactRepository + && deploymentRepository.getAuthentication() == null ) { - MavenSession session = legacySupport.getSession(); + remoteRepo.setAuthentication( session.getAuthenticationSelector().getAuthentication( remoteRepo ) ); + remoteRepo.setProxy( session.getProxySelector().getProxy( remoteRepo ) ); + } + request.setRepository( remoteRepo ); - if ( session != null ) + DeployResult result; + try + { + result = repoSystem.deploy( session, request ); + } + catch ( DeploymentException e ) + { + throw new ArtifactDeploymentException( e.getMessage(), e ); + } + + if ( snapshotKey != null ) + { + for ( Object metadata : result.getMetadata() ) { - MavenExecutionRequest request = session.getRequest(); - - if ( request != null ) + if ( metadata.getClass().getName().endsWith( ".internal.RemoteSnapshotMetadata" ) ) { - List repositories = Arrays.asList( repository ); - - repositorySystem.injectProxy( repositories, request.getProxies() ); - - repositorySystem.injectAuthentication( repositories, request.getServers() ); + snapshots.put( snapshotKey, (MergeableMetadata) metadata ); } } } - return repository; + artifact.setResolvedVersion( result.getArtifacts().iterator().next().getVersion() ); } } diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java b/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java index 049e63e091..3989e49d9f 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java @@ -20,21 +20,27 @@ */ import java.io.File; -import java.io.IOException; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.metadata.RepositoryMetadataInstallationException; -import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager; -import org.apache.maven.repository.DefaultLocalRepositoryMaintainerEvent; -import org.apache.maven.repository.LocalRepositoryMaintainer; -import org.apache.maven.repository.LocalRepositoryMaintainerEvent; -import org.apache.maven.repository.legacy.resolver.transform.ArtifactTransformationManager; +import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata; +import org.apache.maven.artifact.repository.metadata.MetadataBridge; +import org.apache.maven.artifact.repository.metadata.Snapshot; +import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.apache.maven.plugin.LegacySupport; +import org.apache.maven.project.artifact.ProjectArtifactMetadata; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.codehaus.plexus.util.FileUtils; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.installation.InstallRequest; +import org.sonatype.aether.installation.InstallationException; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.sonatype.aether.util.artifact.SubArtifact; /** * @author Jason van Zyl @@ -44,15 +50,13 @@ public class DefaultArtifactInstaller extends AbstractLogEnabled implements ArtifactInstaller { - @Requirement - private ArtifactTransformationManager transformationManager; @Requirement - private RepositoryMetadataManager repositoryMetadataManager; - - @Requirement( optional = true ) - private LocalRepositoryMaintainer localRepositoryMaintainer; - + private RepositorySystem repoSystem; + + @Requirement + private LegacySupport legacySupport; + /** @deprecated we want to use the artifact method only, and ensure artifact.file is set correctly. */ @Deprecated public void install( String basedir, String finalName, Artifact artifact, ArtifactRepository localRepository ) @@ -67,59 +71,64 @@ public void install( String basedir, String finalName, Artifact artifact, Artifa public void install( File source, Artifact artifact, ArtifactRepository localRepository ) throws ArtifactInstallationException { - try + DefaultRepositorySystemSession session = + new DefaultRepositorySystemSession( legacySupport.getRepositorySession() ); + LocalRepository localRepo = new LocalRepository( localRepository.getBasedir() ); + session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( localRepo ) ); + + InstallRequest request = new InstallRequest(); + + org.sonatype.aether.artifact.Artifact mainArtifact = RepositoryUtils.toArtifact( artifact ); + mainArtifact = mainArtifact.setFile( source ); + request.addArtifact( mainArtifact ); + + for ( ArtifactMetadata metadata : artifact.getMetadataList() ) { - transformationManager.transformForInstall( artifact, localRepository ); - - String localPath = localRepository.pathOf( artifact ); - - // TODO: use a file: wagon and the wagon manager? - File destination = new File( localRepository.getBasedir(), localPath ); - if ( !destination.getParentFile().exists() ) + if ( metadata instanceof ProjectArtifactMetadata ) { - destination.getParentFile().mkdirs(); + org.sonatype.aether.artifact.Artifact pomArtifact = new SubArtifact( mainArtifact, "", "pom" ); + pomArtifact = pomArtifact.setFile( ( (ProjectArtifactMetadata) metadata ).getFile() ); + request.addArtifact( pomArtifact ); } - - boolean copy = - !destination.exists() || "pom".equals( artifact.getType() ) - || source.lastModified() != destination.lastModified() || source.length() != destination.length(); - - if ( copy ) + else if ( metadata instanceof SnapshotArtifactRepositoryMetadata + || metadata instanceof ArtifactRepositoryMetadata ) { - getLogger().info( "Installing " + source + " to " + destination ); - - FileUtils.copyFile( source, destination ); - destination.setLastModified( source.lastModified() ); + // eaten, handled by repo system } else { - getLogger().info( "Skipped re-installing " + source + " to " + destination + ", seems unchanged" ); + request.addMetadata( new MetadataBridge( metadata ) ); } + } - // must be after the artifact is installed - for ( ArtifactMetadata metadata : artifact.getMetadataList() ) - { - repositoryMetadataManager.install( metadata, localRepository ); - } - // TODO: would like to flush this, but the plugin metadata is added in advance, not as an install/deploy - // transformation - // This would avoid the need to merge and clear out the state during deployment - // artifact.getMetadataList().clear(); + try + { + repoSystem.install( session, request ); + } + catch ( InstallationException e ) + { + throw new ArtifactInstallationException( e.getMessage(), e ); + } - if ( localRepositoryMaintainer != null ) - { - LocalRepositoryMaintainerEvent event = - new DefaultLocalRepositoryMaintainerEvent( localRepository, artifact, destination ); - localRepositoryMaintainer.artifactInstalled( event ); - } - } - catch ( IOException e ) + /* + * NOTE: Not used by Maven core, only here to provide backward-compat with plugins like the Install Plugin. + */ + + if ( artifact.isSnapshot() ) { - throw new ArtifactInstallationException( "Error installing artifact: " + e.getMessage(), e ); + Snapshot snapshot = new Snapshot(); + snapshot.setLocalCopy( true ); + artifact.addMetadata( new SnapshotArtifactRepositoryMetadata( artifact, snapshot ) ); } - catch ( RepositoryMetadataInstallationException e ) + + Versioning versioning = new Versioning(); + versioning.updateTimestamp(); + versioning.addVersion( artifact.getBaseVersion() ); + if ( artifact.isRelease() ) { - throw new ArtifactInstallationException( "Error installing artifact's metadata: " + e.getMessage(), e ); + versioning.setRelease( artifact.getBaseVersion() ); } + artifact.addMetadata( new ArtifactRepositoryMetadata( artifact, versioning ) ); } -} \ No newline at end of file + +} diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java index dec26f14a8..0f1030b2e6 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java @@ -6,9 +6,9 @@ * 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 @@ -22,7 +22,6 @@ import java.io.Writer; import java.util.Date; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -30,7 +29,6 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.artifact.repository.DefaultRepositoryRequest; -import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer; @@ -49,7 +47,7 @@ /** * @author Jason van Zyl */ -@Component( role = RepositoryMetadataManager.class ) +@Component(role=RepositoryMetadataManager.class) public class DefaultRepositoryMetadataManager extends AbstractLogEnabled implements RepositoryMetadataManager @@ -60,8 +58,7 @@ public class DefaultRepositoryMetadataManager @Requirement private UpdateCheckManager updateCheckManager; - public void resolve( RepositoryMetadata metadata, List remoteRepositories, - ArtifactRepository localRepository ) + public void resolve( RepositoryMetadata metadata, List remoteRepositories, ArtifactRepository localRepository ) throws RepositoryMetadataResolutionException { RepositoryRequest request = new DefaultRepositoryRequest(); @@ -73,41 +70,6 @@ public void resolve( RepositoryMetadata metadata, List remot public void resolve( RepositoryMetadata metadata, RepositoryRequest request ) throws RepositoryMetadataResolutionException { - RepositoryCache cache = request.getCache(); - - CacheKey cacheKey = null; - - if ( cache != null ) - { - cacheKey = new CacheKey( metadata, request ); - - CacheRecord cacheRecord = (CacheRecord) cache.get( request, cacheKey ); - - if ( cacheRecord != null ) - { - if ( getLogger().isDebugEnabled() ) - { - getLogger().debug( "Resolved metadata from cache: " + metadata + " @ " + cacheRecord.repository ); - } - - metadata.setMetadata( MetadataUtils.cloneMetadata( cacheRecord.metadata ) ); - - if ( cacheRecord.repository != null ) - { - for ( ArtifactRepository repository : request.getRemoteRepositories() ) - { - if ( cacheRecord.repository.equals( repository.getId() ) ) - { - metadata.setRepository( repository ); - break; - } - } - } - - return; - } - } - ArtifactRepository localRepository = request.getLocalRepository(); List remoteRepositories = request.getRemoteRepositories(); @@ -209,13 +171,7 @@ else if ( updateCheckManager.isUpdateRequired( metadata, repository, file ) ) } catch ( RepositoryMetadataStoreException e ) { - throw new RepositoryMetadataResolutionException( "Unable to store local copy of metadata: " - + e.getMessage(), e ); - } - - if ( cache != null ) - { - cache.put( request, cacheKey, new CacheRecord( metadata ) ); + throw new RepositoryMetadataResolutionException( "Unable to store local copy of metadata: " + e.getMessage(), e ); } } @@ -226,130 +182,7 @@ private Date getLocalCopyLastModified( ArtifactRepository localRepository, Repos return metadataFile.isFile() ? new Date( metadataFile.lastModified() ) : null; } - private static final class CacheKey - { - - final Object metadataKey; - - final ArtifactRepository localRepository; - - final List remoteRepositories; - - final int hashCode; - - CacheKey( RepositoryMetadata metadata, RepositoryRequest request ) - { - metadataKey = metadata.getKey(); - localRepository = request.getLocalRepository(); - remoteRepositories = request.getRemoteRepositories(); - - int hash = 17; - hash = hash * 31 + metadata.getKey().hashCode(); - hash = hash * 31 + repoHashCode( localRepository ); - for ( ArtifactRepository remoteRepository : remoteRepositories ) - { - hash = hash * 31 + repoHashCode( remoteRepository ); - } - hashCode = hash; - } - - int repoHashCode( ArtifactRepository repository ) - { - return ( repository != null && repository.getUrl() != null ) ? repository.getUrl().hashCode() : 0; - } - - boolean repoEquals( ArtifactRepository repo1, ArtifactRepository repo2 ) - { - if ( repo1 == repo2 ) - { - return true; - } - - if ( repo1 == null || repo2 == null ) - { - return false; - } - - return equal( repo1.getUrl(), repo2.getUrl() ) && repo1.getClass() == repo2.getClass(); - } - - private static boolean equal( T s1, T s2 ) - { - return s1 != null ? s1.equals( s2 ) : s2 == null; - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - - if ( !( obj instanceof CacheKey ) ) - { - return false; - } - - CacheKey that = (CacheKey) obj; - - if ( !this.metadataKey.equals( that.metadataKey ) ) - { - return false; - } - - if ( !repoEquals( this.localRepository, that.localRepository ) ) - { - return false; - } - - for ( Iterator it1 = this.remoteRepositories.iterator(), it2 = - that.remoteRepositories.iterator();; ) - { - if ( !it1.hasNext() || !it2.hasNext() ) - { - if ( it1.hasNext() != it2.hasNext() ) - { - return false; - } - break; - } - ArtifactRepository repo1 = it1.next(); - ArtifactRepository repo2 = it2.next(); - if ( !repoEquals( repo1, repo2 ) ) - { - return false; - } - } - - return true; - } - - @Override - public int hashCode() - { - return hashCode; - } - - } - - private static final class CacheRecord - { - - final Metadata metadata; - - final String repository; - - CacheRecord( RepositoryMetadata metadata ) - { - this.metadata = MetadataUtils.cloneMetadata( metadata.getMetadata() ); - this.repository = ( metadata.getRepository() != null ) ? metadata.getRepository().getId() : null; - } - - } - - private void mergeMetadata( RepositoryMetadata metadata, List remoteRepositories, - ArtifactRepository localRepository ) + private void mergeMetadata( RepositoryMetadata metadata, List remoteRepositories, ArtifactRepository localRepository ) throws RepositoryMetadataStoreException { // TODO: currently this is first wins, but really we should take the latest by comparing either the @@ -378,9 +211,7 @@ private void mergeMetadata( RepositoryMetadata metadata, List previousMetadata, - ArtifactRepository selected, ArtifactRepository localRepository ) + private void updateSnapshotMetadata( RepositoryMetadata metadata, Map previousMetadata, ArtifactRepository selected, ArtifactRepository localRepository ) throws RepositoryMetadataStoreException { // TODO: this could be a lot nicer... should really be in the snapshot transformation? @@ -405,8 +236,7 @@ private void updateSnapshotMetadata( RepositoryMetadata metadata, } else { - if ( ( m.getVersioning() != null ) && ( m.getVersioning().getSnapshot() != null ) - && m.getVersioning().getSnapshot().isLocalCopy() ) + if ( ( m.getVersioning() != null ) && ( m.getVersioning().getSnapshot() != null ) && m.getVersioning().getSnapshot().isLocalCopy() ) { m.getVersioning().getSnapshot().setLocalCopy( false ); metadata.setMetadata( m ); @@ -419,14 +249,11 @@ private void updateSnapshotMetadata( RepositoryMetadata metadata, } } - private boolean loadMetadata( RepositoryMetadata repoMetadata, ArtifactRepository remoteRepository, - ArtifactRepository localRepository, Map previousMetadata ) + private boolean loadMetadata( RepositoryMetadata repoMetadata, ArtifactRepository remoteRepository, ArtifactRepository localRepository, Map previousMetadata ) { boolean setRepository = false; - File metadataFile = - new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( repoMetadata, - remoteRepository ) ); + File metadataFile = new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( repoMetadata, remoteRepository ) ); if ( metadataFile.exists() ) { @@ -488,13 +315,11 @@ protected Metadata readMetadata( File mappingFile ) } catch ( IOException e ) { - throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " - + e.getMessage(), e ); + throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e ); } catch ( XmlPullParserException e ) { - throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " - + e.getMessage(), e ); + throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e ); } finally { @@ -505,8 +330,8 @@ protected Metadata readMetadata( File mappingFile ) } /** - * Ensures the last updated timestamp of the specified metadata does not refer to the future and fixes the local - * metadata if necessary to allow proper merging/updating of metadata during deployment. + * Ensures the last updated timestamp of the specified metadata does not refer to the future and fixes the local metadata if necessary to allow + * proper merging/updating of metadata during deployment. */ private void fixTimestamp( File metadataFile, Metadata metadata, Metadata reference ) { @@ -562,8 +387,7 @@ private void fixTimestamp( File metadataFile, Metadata metadata, Metadata refere } } - public void resolveAlways( RepositoryMetadata metadata, ArtifactRepository localRepository, - ArtifactRepository remoteRepository ) + public void resolveAlways( RepositoryMetadata metadata, ArtifactRepository localRepository, ArtifactRepository remoteRepository ) throws RepositoryMetadataResolutionException { File file; @@ -573,8 +397,7 @@ public void resolveAlways( RepositoryMetadata metadata, ArtifactRepository local } catch ( TransferFailedException e ) { - throw new RepositoryMetadataResolutionException( metadata + " could not be retrieved from repository: " - + remoteRepository.getId() + " due to an error: " + e.getMessage(), e ); + throw new RepositoryMetadataResolutionException( metadata + " could not be retrieved from repository: " + remoteRepository.getId() + " due to an error: " + e.getMessage(), e ); } try @@ -591,24 +414,18 @@ public void resolveAlways( RepositoryMetadata metadata, ArtifactRepository local } } - private File getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, - ArtifactRepository localRepository, - ArtifactRepository remoteRepository ) + private File getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository localRepository, ArtifactRepository remoteRepository ) throws TransferFailedException { - File file = - new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( metadata, - remoteRepository ) ); + File file = new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( metadata, remoteRepository ) ); try { - wagonManager.getArtifactMetadataFromDeploymentRepository( metadata, remoteRepository, file, - ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN ); + wagonManager.getArtifactMetadataFromDeploymentRepository( metadata, remoteRepository, file, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN ); } catch ( ResourceDoesNotExistException e ) { - getLogger().info( metadata + " could not be found on repository: " + remoteRepository.getId() - + ", so will be created" ); + getLogger().info( metadata + " could not be found on repository: " + remoteRepository.getId() + ", so will be created" ); // delete the local copy so the old details aren't used. if ( file.exists() ) @@ -626,8 +443,7 @@ private File getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metad return file; } - public void deploy( ArtifactMetadata metadata, ArtifactRepository localRepository, - ArtifactRepository deploymentRepository ) + public void deploy( ArtifactMetadata metadata, ArtifactRepository localRepository, ArtifactRepository deploymentRepository ) throws RepositoryMetadataDeploymentException { File file; @@ -640,8 +456,7 @@ public void deploy( ArtifactMetadata metadata, ArtifactRepository localRepositor } catch ( TransferFailedException e ) { - throw new RepositoryMetadataDeploymentException( metadata + " could not be retrieved from repository: " - + deploymentRepository.getId() + " due to an error: " + e.getMessage(), e ); + throw new RepositoryMetadataDeploymentException( metadata + " could not be retrieved from repository: " + deploymentRepository.getId() + " due to an error: " + e.getMessage(), e ); } if ( file.isFile() ) @@ -659,9 +474,7 @@ public void deploy( ArtifactMetadata metadata, ArtifactRepository localRepositor else { // It's a POM - we don't need to retrieve it first - file = - new File( localRepository.getBasedir(), - localRepository.pathOfLocalRepositoryMetadata( metadata, deploymentRepository ) ); + file = new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( metadata, deploymentRepository ) ); } try diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java new file mode 100644 index 0000000000..a1fb1e8426 --- /dev/null +++ b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java @@ -0,0 +1,157 @@ +package org.apache.maven.artifact.repository.metadata; + +/* + * 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. + */ + +import java.io.File; + +import org.apache.maven.artifact.metadata.ArtifactMetadata; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.DefaultArtifactRepository; +import org.apache.maven.artifact.repository.metadata.RepositoryMetadata; +import org.codehaus.plexus.util.FileUtils; +import org.sonatype.aether.RepositoryException; +import org.sonatype.aether.metadata.MergeableMetadata; + +/** + * Warning: This is an internal utility class that is only public for technical reasons, it is not part + * of the public API. In particular, this class can be changed or deleted without prior notice. + * + * @author Benjamin Bentmann + */ +public final class MetadataBridge + implements MergeableMetadata +{ + + private ArtifactMetadata metadata; + + private boolean merged; + + public MetadataBridge( ArtifactMetadata metadata ) + { + this.metadata = metadata; + } + + public void merge( File current, File result ) + throws RepositoryException + { + try + { + if ( current.exists() ) + { + FileUtils.copyFile( current, result ); + } + ArtifactRepository localRepo = new MetadataRepository( result ); + metadata.storeInLocalRepository( localRepo, localRepo ); + merged = true; + } + catch ( Exception e ) + { + throw new RepositoryException( e.getMessage(), e ); + } + } + + public boolean isMerged() + { + return merged; + } + + public String getGroupId() + { + return emptify( metadata.getGroupId() ); + } + + public String getArtifactId() + { + return metadata.storedInGroupDirectory() ? "" : emptify( metadata.getArtifactId() ); + } + + public String getVersion() + { + return metadata.storedInArtifactVersionDirectory() ? emptify( metadata.getBaseVersion() ) : ""; + } + + public String getType() + { + return metadata.getRemoteFilename(); + } + + private String emptify( String string ) + { + return ( string != null ) ? string : ""; + } + + public File getFile() + { + return null; + } + + public MetadataBridge setFile( File file ) + { + return this; + } + + public Nature getNature() + { + if ( metadata instanceof RepositoryMetadata ) + { + switch ( ( (RepositoryMetadata) metadata ).getNature() ) + { + case RepositoryMetadata.RELEASE_OR_SNAPSHOT: + return Nature.RELEASE_OR_SNAPSHOT; + case RepositoryMetadata.SNAPSHOT: + return Nature.SNAPSHOT; + default: + return Nature.RELEASE; + } + } + else + { + return Nature.RELEASE; + } + } + + @SuppressWarnings( "deprecation" ) + static class MetadataRepository + extends DefaultArtifactRepository + { + + private File metadataFile; + + public MetadataRepository( File metadataFile ) + { + super( "local", "", null ); + this.metadataFile = metadataFile; + } + + @Override + public String getBasedir() + { + return metadataFile.getParent(); + } + + @Override + public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository ) + { + return metadataFile.getName(); + } + + } + +} diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java b/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java index 13c134ada5..92c0aed291 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java @@ -1,26 +1,21 @@ package org.apache.maven.artifact.resolver; /* - * 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. + * 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. */ import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; @@ -37,57 +32,43 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.metadata.ResolutionGroup; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.DefaultRepositoryRequest; import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.repository.metadata.Metadata; -import org.apache.maven.artifact.repository.metadata.Snapshot; -import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata; -import org.apache.maven.artifact.repository.metadata.Versioning; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; -import org.apache.maven.repository.DefaultLocalRepositoryMaintainerEvent; -import org.apache.maven.repository.LocalRepositoryMaintainer; -import org.apache.maven.repository.LocalRepositoryMaintainerEvent; -import org.apache.maven.repository.legacy.TransferListenerAdapter; -import org.apache.maven.repository.legacy.WagonManager; -import org.apache.maven.repository.legacy.metadata.ArtifactMetadata; import org.apache.maven.repository.legacy.metadata.DefaultMetadataResolutionRequest; import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest; import org.apache.maven.repository.legacy.resolver.conflict.ConflictResolver; -import org.apache.maven.repository.legacy.resolver.transform.ArtifactTransformationManager; -import org.apache.maven.wagon.ResourceDoesNotExistException; -import org.apache.maven.wagon.TransferFailedException; import org.apache.maven.wagon.events.TransferListener; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.Logger; -import org.codehaus.plexus.util.FileUtils; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.ArtifactResult; +import org.sonatype.aether.util.DefaultRepositorySystemSession; /** * @author Jason van Zyl */ -@Component( role = ArtifactResolver.class ) +@Component(role = ArtifactResolver.class) public class DefaultArtifactResolver implements ArtifactResolver { - @Requirement + @Requirement private Logger logger; - @Requirement - private WagonManager wagonManager; - - @Requirement - private ArtifactTransformationManager transformationManager; - @Requirement protected ArtifactFactory artifactFactory; @@ -99,16 +80,16 @@ public class DefaultArtifactResolver @Requirement private ArtifactMetadataSource source; - + @Requirement private PlexusContainer container; - @Requirement( optional = true ) - private LocalRepositoryMaintainer localRepositoryMaintainer; - @Requirement private LegacySupport legacySupport; + @Requirement + private RepositorySystem repoSystem; + private final Executor executor; public DefaultArtifactResolver() @@ -141,13 +122,32 @@ protected void finalize() } } + private RepositorySystemSession getSession( ArtifactRepository localRepository ) + { + MavenSession mavenSession = legacySupport.getSession(); + DefaultRepositorySystemSession session; + if ( mavenSession != null ) + { + session = new DefaultRepositorySystemSession( mavenSession.getRepositorySession() ); + } + else + { + session = new DefaultRepositorySystemSession(); + } + if ( localRepository != null && localRepository.getBasedir() != null ) + { + LocalRepository localRepo = new LocalRepository( localRepository.getBasedir() ); + session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( localRepo ) ); + } + return session; + } + private void injectSession1( RepositoryRequest request, MavenSession session ) { if ( session != null ) { request.setOffline( session.isOffline() ); request.setForceUpdate( session.getRequest().isUpdateSnapshots() ); - request.setTransferListener( session.getRequest().getTransferListener() ); } } @@ -163,297 +163,125 @@ private void injectSession2( ArtifactResolutionRequest request, MavenSession ses } } - public void resolve( Artifact artifact, List remoteRepositories, - ArtifactRepository localRepository, TransferListener resolutionListener ) + public void resolve( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository, TransferListener resolutionListener ) throws ArtifactResolutionException, ArtifactNotFoundException { - RepositoryRequest request = new DefaultRepositoryRequest(); - injectSession1( request, legacySupport.getSession() ); - request.setLocalRepository( localRepository ); - request.setRemoteRepositories( remoteRepositories ); - resolve( artifact, request, resolutionListener, false ); + resolve( artifact, remoteRepositories, getSession( localRepository ) ); } - public void resolveAlways( Artifact artifact, List remoteRepositories, - ArtifactRepository localRepository ) + public void resolveAlways( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository ) throws ArtifactResolutionException, ArtifactNotFoundException { - RepositoryRequest request = new DefaultRepositoryRequest(); - injectSession1( request, legacySupport.getSession() ); - request.setLocalRepository( localRepository ); - request.setRemoteRepositories( remoteRepositories ); - resolve( artifact, request, null, true ); + resolve( artifact, remoteRepositories, getSession( localRepository ) ); } - private void resolve( Artifact artifact, RepositoryRequest request, TransferListener downloadMonitor, - boolean force ) + private void resolve( Artifact artifact, List remoteRepositories, RepositorySystemSession session ) throws ArtifactResolutionException, ArtifactNotFoundException { if ( artifact == null ) { return; } - - File destination; - + if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) ) { File systemFile = artifact.getFile(); if ( systemFile == null ) { - throw new ArtifactNotFoundException( "System artifact: " + artifact + " has no file attached", - artifact ); + throw new ArtifactNotFoundException( "System artifact: " + artifact + " has no file attached", artifact ); } if ( !systemFile.exists() ) { - throw new ArtifactNotFoundException( "System artifact: " + artifact + " not found in path: " - + systemFile, artifact ); + throw new ArtifactNotFoundException( "System artifact: " + artifact + " not found in path: " + systemFile, artifact ); } if ( !systemFile.isFile() ) { - throw new ArtifactNotFoundException( "System artifact: " + artifact + " is not a file: " + systemFile, - artifact ); + throw new ArtifactNotFoundException( "System artifact: " + artifact + " is not a file: " + systemFile, artifact ); } artifact.setResolved( true ); - + return; } - ArtifactRepository localRepository = request.getLocalRepository(); - - List remoteRepositories = request.getRemoteRepositories(); - if ( !artifact.isResolved() ) { - // ---------------------------------------------------------------------- - // Check for the existence of the artifact in the specified local - // ArtifactRepository. If it is present then simply return as the - // request for resolution has been satisfied. - // ---------------------------------------------------------------------- + ArtifactResult result; - artifact = localRepository.find( artifact ); - - if ( artifact.isResolved() ) + try { - return; + ArtifactRequest artifactRequest = new ArtifactRequest(); + artifactRequest.setArtifact( RepositoryUtils.toArtifact( artifact ) ); + artifactRequest.setRepositories( RepositoryUtils.toRepos( remoteRepositories ) ); + result = repoSystem.resolveArtifact( session, artifactRequest ); } - - transformationManager.transformForResolve( artifact, request ); - - destination = artifact.getFile(); - - if ( !request.isOffline() && ( force || !destination.exists() || isMutable( artifact ) ) ) + catch ( org.sonatype.aether.resolution.ArtifactResolutionException e ) { - try - { - if ( artifact.getRepository() != null ) - { - // the transformations discovered the artifact - so use it exclusively - wagonManager.getArtifact( artifact, artifact.getRepository(), downloadMonitor, - request.isForceUpdate() ); - } - else - { - wagonManager.getArtifact( artifact, remoteRepositories, downloadMonitor, - request.isForceUpdate() ); - } - - if ( localRepositoryMaintainer != null ) - { - LocalRepositoryMaintainerEvent event = - new DefaultLocalRepositoryMaintainerEvent( localRepository, artifact, null ); - localRepositoryMaintainer.artifactDownloaded( event ); - } - - } - catch ( ResourceDoesNotExistException e ) + if ( e.getCause() instanceof org.sonatype.aether.transfer.ArtifactNotFoundException ) { throw new ArtifactNotFoundException( e.getMessage(), artifact, remoteRepositories, e ); } - catch ( TransferFailedException e ) + else { throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e ); } } - if ( destination.exists() ) - { - artifact.setResolved( true ); - } - else - { - if ( request.isOffline() ) - { - throw new ArtifactResolutionException( "The repository system is offline" - + " and the requested artifact is not locally available at " + destination, artifact, - remoteRepositories ); - } - else - { - throw new ArtifactResolutionException( "Failed to resolve artifact, possibly due to a " - + "repository list that is not appropriately equipped for this artifact's metadata.", artifact, - remoteRepositories ); - } - } - - // 1.0-SNAPSHOT - // - // 1) pom = 1.0-SNAPSHOT - // 2) pom = 1.0-yyyymmdd.hhmmss - // 3) baseVersion = 1.0-SNAPSHOT - if ( artifact.isSnapshot() && isTimestamped( artifact ) ) - { - String version = artifact.getVersion(); - - // 1.0-SNAPSHOT - artifact.selectVersion( artifact.getBaseVersion() ); - - // Make a file with a 1.0-SNAPSHOT format - File copy = new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) ); - - // if the timestamped version was resolved or the copy doesn't exist then copy a version - // of the file like 1.0-SNAPSHOT. Even if there is a timestamped version the non-timestamped - // version will be created. - if ( !copy.exists() || copy.lastModified() != destination.lastModified() - || copy.length() != destination.length() ) - { - // recopy file if it was reresolved, or doesn't exist. - try - { - FileUtils.copyFile( destination, copy ); - - copy.setLastModified( destination.lastModified() ); - } - catch ( IOException e ) - { - throw new ArtifactResolutionException( "Unable to copy resolved artifact for local use: " - + e.getMessage(), artifact, remoteRepositories, e ); - } - } - - // We are only going to use the 1.0-SNAPSHOT version - artifact.setFile( copy ); - - // Set the version to the 1.0-yyyymmdd.hhmmss version - artifact.selectVersion( version ); - } + artifact.selectVersion( result.getArtifact().getVersion() ); + artifact.setFile( result.getArtifact().getFile() ); + artifact.setResolved( true ); } } - private boolean isMutable( Artifact artifact ) - { - return artifact.isSnapshot() && !isTimestamped( artifact ) && !isLocalCopy( artifact ); - } - - private boolean isTimestamped( Artifact artifact ) - { - return !artifact.getBaseVersion().equals( artifact.getVersion() ); - } - - private boolean isLocalCopy( Artifact artifact ) - { - boolean localCopy = false; - - for ( ArtifactMetadata m : artifact.getMetadataList() ) - { - if ( m instanceof SnapshotArtifactRepositoryMetadata ) - { - SnapshotArtifactRepositoryMetadata snapshotMetadata = (SnapshotArtifactRepositoryMetadata) m; - - Metadata metadata = snapshotMetadata.getMetadata(); - - if ( metadata != null ) - { - Versioning versioning = metadata.getVersioning(); - - if ( versioning != null ) - { - Snapshot snapshot = versioning.getSnapshot(); - - if ( snapshot != null ) - { - // TODO is it possible to have more than one SnapshotArtifactRepositoryMetadata - localCopy = snapshot.isLocalCopy(); - } - } - } - } - } - - return localCopy; - } - - public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, - ArtifactRepository localRepository, - List remoteRepositories, + public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source, ArtifactFilter filter ) throws ArtifactResolutionException, ArtifactNotFoundException { - return resolveTransitively( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, - remoteRepositories, source, filter ); + return resolveTransitively( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories, source, filter ); } - public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, - Map managedVersions, ArtifactRepository localRepository, - List remoteRepositories, - ArtifactMetadataSource source ) + public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, Map managedVersions, ArtifactRepository localRepository, + List remoteRepositories, ArtifactMetadataSource source ) throws ArtifactResolutionException, ArtifactNotFoundException { - return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository, - remoteRepositories, source, null ); + return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository, remoteRepositories, source, null ); } - public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, - Map managedVersions, ArtifactRepository localRepository, - List remoteRepositories, - ArtifactMetadataSource source, ArtifactFilter filter ) + public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, Map managedVersions, ArtifactRepository localRepository, + List remoteRepositories, ArtifactMetadataSource source, ArtifactFilter filter ) throws ArtifactResolutionException, ArtifactNotFoundException { - return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository, - remoteRepositories, source, filter, null ); + return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository, remoteRepositories, source, filter, null ); } - public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, - List remoteRepositories, - ArtifactRepository localRepository, + public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, List remoteRepositories, ArtifactRepository localRepository, ArtifactMetadataSource source ) throws ArtifactResolutionException, ArtifactNotFoundException { return resolveTransitively( artifacts, originatingArtifact, localRepository, remoteRepositories, source, null ); } - public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, - List remoteRepositories, - ArtifactRepository localRepository, - ArtifactMetadataSource source, - List listeners ) + public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, List remoteRepositories, ArtifactRepository localRepository, + ArtifactMetadataSource source, List listeners ) throws ArtifactResolutionException, ArtifactNotFoundException { return resolveTransitively( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories, source, null, listeners ); } - public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, - Map managedVersions, ArtifactRepository localRepository, - List remoteRepositories, - ArtifactMetadataSource source, ArtifactFilter filter, - List listeners ) + public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, Map managedVersions, ArtifactRepository localRepository, + List remoteRepositories, ArtifactMetadataSource source, ArtifactFilter filter, List listeners ) throws ArtifactResolutionException, ArtifactNotFoundException { - return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository, - remoteRepositories, source, filter, listeners, null ); + return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository, remoteRepositories, source, filter, listeners, null ); } - public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, - Map managedVersions, ArtifactRepository localRepository, - List remoteRepositories, - ArtifactMetadataSource source, ArtifactFilter filter, - List listeners, + public ArtifactResolutionResult resolveTransitively( Set artifacts, Artifact originatingArtifact, Map managedVersions, ArtifactRepository localRepository, + List remoteRepositories, ArtifactMetadataSource source, ArtifactFilter filter, List listeners, List conflictResolvers ) throws ArtifactResolutionException, ArtifactNotFoundException { @@ -461,7 +289,7 @@ public ArtifactResolutionResult resolveTransitively( Set artifacts, Ar .setArtifact( originatingArtifact ) .setResolveRoot( false ) // This is required by the surefire plugin - .setArtifactDependencies( artifacts ) + .setArtifactDependencies( artifacts ) .setManagedVersionMap( managedVersions ) .setLocalRepository( localRepository ) .setRemoteRepositories( remoteRepositories ) @@ -497,10 +325,10 @@ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request ) Set artifacts = request.getArtifactDependencies(); Map managedVersions = request.getManagedVersionMap(); List listeners = request.getListeners(); - ArtifactFilter collectionFilter = request.getCollectionFilter(); + ArtifactFilter collectionFilter = request.getCollectionFilter(); ArtifactFilter resolutionFilter = request.getResolutionFilter(); - TransferListener transferListener = TransferListenerAdapter.newAdapter( request.getTransferListener() ); - + RepositorySystemSession session = getSession( request.getLocalRepository() ); + //TODO: hack because metadata isn't generated in m2e correctly and i want to run the maven i have in the workspace if ( source == null ) { @@ -532,12 +360,12 @@ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request ) // This is often an artifact like a POM that is taken from disk and we already have hold of the // file reference. But this may be a Maven Plugin that we need to resolve from a remote repository // as well as its dependencies. - + if ( request.isResolveRoot() /* && rootArtifact.getFile() == null */ ) - { + { try { - resolve( rootArtifact, request, transferListener, false ); + resolve( rootArtifact, request.getRemoteRepositories(), session ); } catch ( ArtifactResolutionException e ) { @@ -609,7 +437,7 @@ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request ) return result; } } - + if ( artifacts == null || artifacts.isEmpty() ) { if ( request.isResolveRoot() ) @@ -617,19 +445,18 @@ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request ) result.addArtifact( rootArtifact ); } return result; - } + } // After the collection we will have the artifact object in the result but they will not be resolved yet. result = artifactCollector.collect( artifacts, rootArtifact, managedVersions, collectionRequest, source, collectionFilter, listeners, null ); - + // We have metadata retrieval problems, or there are cycles that have been detected // so we give this back to the calling code and let them deal with this information // appropriately. - if ( result.hasMetadataResolutionExceptions() || result.hasVersionRangeViolations() - || result.hasCircularDependencyExceptions() ) + if ( result.hasMetadataResolutionExceptions() || result.hasVersionRangeViolations() || result.hasCircularDependencyExceptions() ) { return result; } @@ -646,11 +473,8 @@ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request ) if ( resolutionFilter == null || resolutionFilter.include( artifact ) ) { - ArtifactResolutionRequest childRequest = new ArtifactResolutionRequest( request ); - childRequest.setRemoteRepositories( node.getRemoteRepositories() ); - - executor.execute( new ResolveTask( classLoader, latch, artifact, transferListener, childRequest, - result ) ); + executor.execute( new ResolveTask( classLoader, latch, artifact, session, + node.getRemoteRepositories(), result ) ); } else { @@ -671,19 +495,18 @@ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request ) // We want to send the root artifact back in the result but we need to do this after the other dependencies // have been resolved. if ( request.isResolveRoot() ) - { + { // Add the root artifact (as the first artifact to retain logical order of class path!) Set allArtifacts = new LinkedHashSet(); allArtifacts.add( rootArtifact ); allArtifacts.addAll( result.getArtifacts() ); result.setArtifacts( allArtifacts ); - } - + } + return result; } - public void resolve( Artifact artifact, List remoteRepositories, - ArtifactRepository localRepository ) + public void resolve( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository ) throws ArtifactResolutionException, ArtifactNotFoundException { resolve( artifact, remoteRepositories, localRepository, null ); @@ -719,21 +542,20 @@ private class ResolveTask private final Artifact artifact; - private final TransferListener transferListener; + private final RepositorySystemSession session; - private final ArtifactResolutionRequest request; + private final List remoteRepositories; private final ArtifactResolutionResult result; - public ResolveTask( ClassLoader classLoader, CountDownLatch latch, Artifact artifact, - TransferListener transferListener, ArtifactResolutionRequest request, - ArtifactResolutionResult result ) + public ResolveTask( ClassLoader classLoader, CountDownLatch latch, Artifact artifact, RepositorySystemSession session, + List remoteRepositories, ArtifactResolutionResult result ) { this.classLoader = classLoader; this.latch = latch; this.artifact = artifact; - this.transferListener = transferListener; - this.request = request; + this.session = session; + this.remoteRepositories = remoteRepositories; this.result = result; } @@ -742,7 +564,7 @@ public void run() try { Thread.currentThread().setContextClassLoader( classLoader ); - resolve( artifact, request, transferListener, false ); + resolve( artifact, remoteRepositories, session ); } catch ( ArtifactNotFoundException anfe ) { diff --git a/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java b/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java index 9981a8a253..6c2ef2d428 100644 --- a/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java +++ b/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java @@ -94,6 +94,7 @@ private ProjectBuildingRequest injectSession( ProjectBuildingRequest request ) MavenSession session = legacySupport.getSession(); if ( session != null ) { + request.setRepositorySession( session.getRepositorySession() ); request.setOffline( session.isOffline() ); request.setSystemProperties( session.getSystemProperties() ); if ( request.getUserProperties().isEmpty() ) @@ -108,7 +109,6 @@ private ProjectBuildingRequest injectSession( ProjectBuildingRequest request ) request.setMirrors( req.getMirrors() ); request.setProxies( req.getProxies() ); request.setRemoteRepositories( req.getRemoteRepositories() ); - request.setTransferListener( req.getTransferListener() ); request.setForceUpdate( req.isUpdateSnapshots() ); } } diff --git a/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java b/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java index 90e85c5d85..651d46e8ce 100644 --- a/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java +++ b/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java @@ -83,7 +83,6 @@ private void injectSession( ArtifactResolutionRequest request ) request.setServers( session.getRequest().getServers() ); request.setMirrors( session.getRequest().getMirrors() ); request.setProxies( session.getRequest().getProxies() ); - request.setTransferListener( session.getRequest().getTransferListener() ); } } diff --git a/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java b/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java index db7fceb7c6..341afca853 100644 --- a/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java +++ b/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java @@ -29,11 +29,33 @@ import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.plugin.LegacySupport; import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; -import org.apache.maven.artifact.repository.DefaultArtifactRepository; import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.DefaultMavenExecutionResult; +import org.apache.maven.execution.MavenSession; import org.codehaus.plexus.PlexusTestCase; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.collection.DependencyGraphTransformer; +import org.sonatype.aether.collection.DependencyManager; +import org.sonatype.aether.collection.DependencySelector; +import org.sonatype.aether.collection.DependencyTraverser; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.sonatype.aether.util.graph.manager.ClassicDependencyManager; +import org.sonatype.aether.util.graph.selector.AndDependencySelector; +import org.sonatype.aether.util.graph.selector.ExclusionDependencySelector; +import org.sonatype.aether.util.graph.selector.OptionalDependencySelector; +import org.sonatype.aether.util.graph.selector.ScopeDependencySelector; +import org.sonatype.aether.util.graph.transformer.ChainedDependencyGraphTransformer; +import org.sonatype.aether.util.graph.transformer.NearestVersionConflictResolver; +import org.sonatype.aether.util.graph.transformer.ConflictMarker; +import org.sonatype.aether.util.graph.transformer.JavaDependencyContextRefiner; +import org.sonatype.aether.util.graph.transformer.JavaEffectiveScopeCalculator; +import org.sonatype.aether.util.graph.traverser.FatArtifactTraverser; /** * @author Jason van Zyl @@ -53,6 +75,14 @@ protected void setUp() super.setUp(); artifactFactory = lookup( ArtifactFactory.class); artifactRepositoryFactory = lookup( ArtifactRepositoryFactory.class ); + + RepositorySystemSession repoSession = initRepoSession(); + MavenSession session = + new MavenSession( getContainer(), repoSession, new DefaultMavenExecutionRequest(), + new DefaultMavenExecutionResult() ); + + LegacySupport legacySupport = lookup(LegacySupport.class); + legacySupport.setSession( session ); } @Override @@ -297,4 +327,33 @@ protected void deleteArtifact( Artifact artifact, ArtifactRepository repository } } } + + protected RepositorySystemSession initRepoSession() + throws Exception + { + DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(); + session.setIgnoreMissingArtifactDescriptor( true ); + session.setIgnoreInvalidArtifactDescriptor( true ); + DependencyTraverser depTraverser = new FatArtifactTraverser(); + session.setDependencyTraverser( depTraverser ); + + DependencyManager depManager = new ClassicDependencyManager(); + session.setDependencyManager( depManager ); + + DependencySelector depFilter = + new AndDependencySelector( new ScopeDependencySelector( "test", "provided" ), + new OptionalDependencySelector(), new ExclusionDependencySelector() ); + session.setDependencySelector( depFilter ); + + DependencyGraphTransformer transformer = + new ChainedDependencyGraphTransformer( new ConflictMarker(), new JavaEffectiveScopeCalculator(), + new NearestVersionConflictResolver(), + new JavaDependencyContextRefiner() ); + session.setDependencyGraphTransformer( transformer ); + + session.setLocalRepositoryManager( new SimpleLocalRepositoryManager( localRepository().getBasedir() ) ); + + return session; + } + } diff --git a/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java index 36025f7da9..49cfa6a328 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java +++ b/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java @@ -27,6 +27,7 @@ import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.repository.internal.MavenRepositorySystemSession; import org.codehaus.plexus.PlexusTestCase; /** @@ -129,6 +130,7 @@ protected MavenProject getProjectWithDependencies( File pom ) configuration.setRemoteRepositories( Arrays.asList( new ArtifactRepository[] {} ) ); configuration.setProcessPlugins( false ); configuration.setResolveDependencies( true ); + initRepoSession( configuration ); try { @@ -157,8 +159,17 @@ protected MavenProject getProject( File pom ) { ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setLocalRepository( getLocalRepository() ); + initRepoSession( configuration ); return projectBuilder.build( pom, configuration ).getProject(); } + protected void initRepoSession( ProjectBuildingRequest request ) + { + File localRepo = new File( request.getLocalRepository().getBasedir() ); + MavenRepositorySystemSession session = new MavenRepositorySystemSession(); + session.setLocalRepositoryManager( new LegacyLocalRepositoryManager( localRepo ) ); + request.setRepositorySession( session ); + } + } diff --git a/maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java b/maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java new file mode 100644 index 0000000000..9dbb1257e5 --- /dev/null +++ b/maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java @@ -0,0 +1,82 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.impl.ArtifactResolver; +import org.sonatype.aether.impl.internal.DefaultArtifactResolver; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.ArtifactResolutionException; +import org.sonatype.aether.resolution.ArtifactResult; +import org.sonatype.aether.transfer.ArtifactNotFoundException; + +/** + * @author Benjamin Bentmann + */ +@Component( role = ArtifactResolver.class, hint = "classpath" ) +public class ClasspathArtifactResolver + extends DefaultArtifactResolver +{ + + public List resolveArtifacts( RepositorySystemSession session, + Collection requests ) + throws ArtifactResolutionException + { + List results = new ArrayList(); + + for ( ArtifactRequest request : requests ) + { + ArtifactResult result = new ArtifactResult( request ); + results.add( result ); + + Artifact artifact = request.getArtifact(); + if ( "maven-test".equals( artifact.getGroupId() ) ) + { + String scope = artifact.getArtifactId().substring( "scope-".length() ); + + try + { + artifact = artifact.setFile( ProjectClasspathTest.getFileForClasspathResource( ProjectClasspathTest.dir + + "transitive-" + scope + "-dep.xml" ) ); + result.setArtifact( artifact ); + } + catch ( FileNotFoundException e ) + { + throw new IllegalStateException( "Missing test POM for " + artifact ); + } + } + else + { + result.addException( new ArtifactNotFoundException( artifact, null ) ); + throw new ArtifactResolutionException( results ); + } + } + + return results; + } + +} diff --git a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java index e9bdd7184c..fd7542230f 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java +++ b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java @@ -26,17 +26,9 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.*; -import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; -import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginNotFoundException; -import org.apache.maven.plugin.PluginResolutionException; -import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; -import org.apache.maven.plugin.version.PluginVersionResolutionException; /** * A stub implementation that assumes an empty lifecycle to bypass interaction with the plugin manager and to avoid @@ -49,8 +41,6 @@ public class EmptyLifecycleExecutor { public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) - throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, - MojoNotFoundException { return new MavenExecutionPlan(null, null, null, new DefaultLifecycles() ); } @@ -102,14 +92,10 @@ private Plugin newPlugin( String artifactId, String... goals ) } public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, - PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, - LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException { } public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws LifecycleExecutionException { return Collections.emptyList(); } diff --git a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java new file mode 100644 index 0000000000..5a78a7e538 --- /dev/null +++ b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java @@ -0,0 +1,78 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; + +/** + * @author Benjamin Bentmann + */ +public class EmptyLifecyclePluginAnalyzer + implements LifeCyclePluginAnalyzer +{ + public Set getPluginsBoundByDefaultToAllLifecycles( String packaging ) + { + Set plugins; + + // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests + if ( "JAR".equals( packaging ) ) + { + plugins = new LinkedHashSet(); + + plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) ); + plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) ); + plugins.add( newPlugin( "maven-surefire-plugin", "test" ) ); + plugins.add( newPlugin( "maven-jar-plugin", "jar" ) ); + plugins.add( newPlugin( "maven-install-plugin", "install" ) ); + plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) ); + } + else + { + plugins = Collections.emptySet(); + } + + return plugins; + } + + private Plugin newPlugin( String artifactId, String... goals ) + { + Plugin plugin = new Plugin(); + + plugin.setGroupId( "org.apache.maven.plugins" ); + plugin.setArtifactId( artifactId ); + + for ( String goal : goals ) + { + PluginExecution pluginExecution = new PluginExecution(); + pluginExecution.setId( "default-" + goal ); + pluginExecution.addGoal( goal ); + plugin.addExecution( pluginExecution ); + } + + return plugin; + } + +} diff --git a/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java b/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java new file mode 100644 index 0000000000..14b4c26e4c --- /dev/null +++ b/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java @@ -0,0 +1,59 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.io.File; + +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; + +/** + * @author Benjamin Bentmann + */ +public class LegacyLocalRepositoryManager + extends SimpleLocalRepositoryManager +{ + + public LegacyLocalRepositoryManager( File basedir ) + { + super( basedir ); + } + + public String getPathForLocalArtifact( Artifact artifact ) + { + StringBuilder path = new StringBuilder( 128 ); + + path.append( artifact.getGroupId() ).append( '/' ); + + path.append( artifact.getExtension() ).append( 's' ).append( '/' ); + + path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() ); + + if ( artifact.getClassifier().length() > 0 ) + { + path.append( '-' ).append( artifact.getClassifier() ); + } + + path.append( '.' ).append( artifact.getExtension() ); + + return path.toString(); + } + +} diff --git a/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java b/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java index b1766b2709..b84733c1d6 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java +++ b/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java @@ -24,6 +24,9 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader; +import org.sonatype.aether.impl.ArtifactDescriptorReader; +import org.sonatype.aether.impl.ArtifactResolver; public class ProjectClasspathTest extends AbstractMavenProjectTestCase @@ -33,11 +36,15 @@ public class ProjectClasspathTest public void setUp() throws Exception { + ArtifactResolver resolver = lookup( ArtifactResolver.class, "classpath" ); + DefaultArtifactDescriptorReader pomReader = (DefaultArtifactDescriptorReader)lookup(ArtifactDescriptorReader.class); + pomReader.setArtifactResolver( resolver ); + projectBuilder = lookup( ProjectBuilder.class, "classpath" ); // the metadata source looks up the default impl, so we have to trick it getContainer().addComponent( projectBuilder, ProjectBuilder.class, "default" ); - + repositorySystem = lookup( RepositorySystem.class ); } diff --git a/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java b/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java index b931787c07..64f359cecc 100644 --- a/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java +++ b/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java @@ -24,11 +24,17 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ResolutionErrorHandler; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.DefaultMavenExecutionResult; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.model.Repository; import org.apache.maven.model.RepositoryPolicy; +import org.apache.maven.plugin.LegacySupport; import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.PlexusTestCase; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; +import org.sonatype.aether.util.DefaultRepositorySystemSession; /** * Tests {@link LegacyRepositorySystem}. @@ -107,6 +113,12 @@ public void testThatASystemScopedDependencyIsNotResolvedFromRepositories() .setRemoteRepositories( getRemoteRepositories() ) .setLocalRepository( getLocalRepository() ); + DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(); + session.setLocalRepositoryManager( new SimpleLocalRepositoryManager( request.getLocalRepository().getBasedir() ) ); + LegacySupport legacySupport = lookup( LegacySupport.class ); + legacySupport.setSession( new MavenSession( getContainer(), session, new DefaultMavenExecutionRequest(), + new DefaultMavenExecutionResult() ) ); + ArtifactResolutionResult result = repositorySystem.resolve( request ); resolutionErrorHandler.throwErrors( request, result ); assertEquals( 2, result.getArtifacts().size() ); diff --git a/maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/IdeWorkspaceRepositoryTest.java b/maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/IdeWorkspaceRepositoryTest.java deleted file mode 100644 index f15b6b6995..0000000000 --- a/maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/IdeWorkspaceRepositoryTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.apache.maven.repository.ideworkspace; - -import java.io.File; -import java.util.ArrayList; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.repository.DelegatingLocalArtifactRepository; -import org.apache.maven.repository.RepositorySystem; -import org.codehaus.plexus.PlexusTestCase; - -public class IdeWorkspaceRepositoryTest - extends PlexusTestCase -{ - - private RepositorySystem repositorySystem; - private ArtifactRepository localRepository; - - @Override - protected void setUp() - throws Exception - { - super.setUp(); - - repositorySystem = lookup( RepositorySystem.class ); - localRepository = repositorySystem.createLocalRepository( new File( "target/IdeWorkspaceRepositoryTest" ).getCanonicalFile() ); - } - - @Override - protected void tearDown() - throws Exception - { - repositorySystem = null; - localRepository = null; - - super.tearDown(); - } - - public void testResolveFromWorkspace() - throws Exception - { - - Artifact artifact = - repositorySystem.createArtifact( TestIdeWorkspaceRepository.GROUP_ID, TestIdeWorkspaceRepository.ARTIFACT_ID, - TestIdeWorkspaceRepository.VERSION, "jar" ); - - ArtifactResolutionRequest request = new ArtifactResolutionRequest(); - request.setArtifact( artifact ); - request.setLocalRepository( localRepository ); - request.setRemoteRepositories( new ArrayList() ); - - repositorySystem.resolve( request ); - - assertTrue( artifact.isResolved() ); - assertEquals( TestIdeWorkspaceRepository.ARTIFACT_FILE, artifact.getFile() ); - assertSame( localRepository, request.getLocalRepository() ); - } - - public void testDelegatingLocalRepo() - throws Exception - { - Artifact artifact = - repositorySystem.createArtifact( TestIdeWorkspaceRepository.GROUP_ID, TestIdeWorkspaceRepository.ARTIFACT_ID, - TestIdeWorkspaceRepository.VERSION, "jar" ); - - DelegatingLocalArtifactRepository delegatingLocalArtifactRepository = new DelegatingLocalArtifactRepository( localRepository ); - - ArtifactResolutionRequest request = new ArtifactResolutionRequest(); - request.setArtifact( artifact ); - request.setLocalRepository( delegatingLocalArtifactRepository ); - request.setRemoteRepositories( new ArrayList() ); - - repositorySystem.resolve( request ); - - assertTrue( artifact.isResolved() ); - assertEquals( TestIdeWorkspaceRepository.ARTIFACT_FILE, artifact.getFile() ); - - // make sure we restore original repository - assertSame( delegatingLocalArtifactRepository, request.getLocalRepository() ); - assertNull( delegatingLocalArtifactRepository.getIdeWorspace() ); - } -} diff --git a/maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/TestIdeWorkspaceRepository.java b/maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/TestIdeWorkspaceRepository.java deleted file mode 100644 index d1beeb5c26..0000000000 --- a/maven-compat/src/test/java/org/apache/maven/repository/ideworkspace/TestIdeWorkspaceRepository.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.apache.maven.repository.ideworkspace; - -import java.io.File; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.repository.LocalArtifactRepository; -import org.codehaus.plexus.component.annotations.Component; - -@Component( role = LocalArtifactRepository.class, hint = LocalArtifactRepository.IDE_WORKSPACE ) -public class TestIdeWorkspaceRepository - extends LocalArtifactRepository -{ - - public static final String GROUP_ID = "test"; - - public static final String ARTIFACT_ID = "test"; - - public static final String VERSION = "1.0.0-SNAPSHOT"; - - public static final File ARTIFACT_FILE = new File( "/a/b/c/d" ); - - @Override - public Artifact find( Artifact artifact ) - { - if ( GROUP_ID.equals( artifact.getGroupId() ) && ARTIFACT_ID.equals( artifact.getArtifactId() ) - && VERSION.equals( artifact.getVersion() ) ) - { - artifact.setFile( ARTIFACT_FILE ); - artifact.setResolved( true ); - } - return artifact; - } - - @Override - public boolean hasLocalMetadata() - { - return false; - } - -} diff --git a/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml b/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml index c748a6d26a..2666d8dcca 100644 --- a/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml +++ b/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml @@ -30,16 +30,6 @@ under the License. default logger - - org.apache.maven.repository.legacy.WagonManager - default - wagonManager - - - org.apache.maven.repository.legacy.resolver.transform.ArtifactTransformationManager - default - transformationManager - org.apache.maven.artifact.factory.ArtifactFactory default @@ -65,17 +55,16 @@ under the License. default container - - org.apache.maven.repository.LocalRepositoryMaintainer - default - localRepositoryMaintainer - true - org.apache.maven.plugin.LegacySupport default legacySupport + + org.sonatype.aether.RepositorySystem + default + repoSystem + diff --git a/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml index c6769290d4..bcc291e174 100644 --- a/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml +++ b/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml @@ -2,8 +2,8 @@ - org.apache.maven.lifecycle.LifecycleExecutor - org.apache.maven.project.EmptyLifecycleExecutor + org.apache.maven.lifecycle.LifeCyclePluginAnalyzer + org.apache.maven.project.EmptyLifecyclePluginAnalyzer diff --git a/maven-core/pom.xml b/maven-core/pom.xml index dbcd48b720..e379dc810d 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -53,6 +53,15 @@ org.apache.maven maven-model-builder + + org.apache.maven + maven-aether-provider + + + org.sonatype.aether + aether-impl + ${aetherVersion} + org.sonatype.spice diff --git a/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java b/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java index 949bb639cb..7f0fe1cd19 100644 --- a/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java +++ b/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java @@ -19,6 +19,8 @@ * under the License. */ +import java.util.Set; + import org.apache.maven.artifact.resolver.filter.ArtifactFilter; public interface ArtifactFilterManager @@ -39,4 +41,7 @@ public interface ArtifactFilterManager * @param artifactId */ void excludeArtifact( String artifactId ); -} \ No newline at end of file + + Set getCoreArtifactExcludes(); + +} diff --git a/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java b/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java index d7863984b6..abee4470ff 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java @@ -59,6 +59,7 @@ public class DefaultArtifactFilterManager artifacts.add( "plexus:plexus-container-default" ); artifacts.add( "org.sonatype.spice:spice-inject-plexus" ); artifacts.add( "org.apache.maven:maven-artifact" ); + artifacts.add( "org.apache.maven:maven-aether-provider" ); artifacts.add( "org.apache.maven:maven-artifact-manager" ); artifacts.add( "org.apache.maven:maven-compat" ); artifacts.add( "org.apache.maven:maven-core" ); @@ -78,6 +79,8 @@ public class DefaultArtifactFilterManager artifacts.add( "org.apache.maven:maven-settings-builder" ); artifacts.add( "org.apache.maven:maven-toolchain" ); artifacts.add( "org.apache.maven.wagon:wagon-provider-api" ); + artifacts.add( "org.sonatype.aether:aether-api" ); + artifacts.add( "org.sonatype.aether:aether-spi" ); /* * NOTE: Don't exclude the wagons or any of their dependencies (apart from the wagon API). This would otherwise @@ -120,18 +123,11 @@ public ArtifactFilter getArtifactFilter() /** * Returns the artifact filter for the standard core artifacts. * - * @see org.apache.maven.ArtifactFilterManager#getExtensionArtifactFilter() + * @see org.apache.maven.ArtifactFilterManager#getExtensionDependencyFilter() */ public ArtifactFilter getCoreArtifactFilter() { - Set excludes = new LinkedHashSet( DEFAULT_EXCLUSIONS ); - - for ( ArtifactFilterManagerDelegate delegate : getDelegates() ) - { - delegate.addCoreExcludes( excludes ); - } - - return new ExclusionSetFilter( excludes ); + return new ExclusionSetFilter( getCoreArtifactExcludes() ); } private List getDelegates() @@ -154,4 +150,16 @@ public void excludeArtifact( String artifactId ) excludedArtifacts.add( artifactId ); } + public Set getCoreArtifactExcludes() + { + Set excludes = new LinkedHashSet( DEFAULT_EXCLUSIONS ); + + for ( ArtifactFilterManagerDelegate delegate : getDelegates() ) + { + delegate.addCoreExcludes( excludes ); + } + + return excludes; + } + } diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 7cef5e89e7..47e25ef531 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -1,22 +1,18 @@ package org.apache.maven; /* - * 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. + * 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. */ import java.io.File; @@ -33,6 +29,7 @@ import java.util.Map; import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.MavenExecutionRequest; @@ -47,6 +44,7 @@ import org.apache.maven.model.building.ModelProblemUtils; import org.apache.maven.model.building.ModelSource; import org.apache.maven.model.building.UrlModelSource; +import org.apache.maven.plugin.LegacySupport; import org.apache.maven.project.DuplicateProjectException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuilder; @@ -56,6 +54,13 @@ import org.apache.maven.project.ProjectSorter; import org.apache.maven.repository.DelegatingLocalArtifactRepository; import org.apache.maven.repository.LocalRepositoryNotAccessibleException; +import org.apache.maven.settings.Mirror; +import org.apache.maven.settings.Proxy; +import org.apache.maven.settings.Server; +import org.apache.maven.settings.building.SettingsProblem; +import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; +import org.apache.maven.settings.crypto.SettingsDecrypter; +import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; @@ -63,11 +68,39 @@ import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.dag.CycleDetectedException; +import org.sonatype.aether.RepositoryEvent; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.collection.DependencyGraphTransformer; +import org.sonatype.aether.collection.DependencyManager; +import org.sonatype.aether.collection.DependencySelector; +import org.sonatype.aether.collection.DependencyTraverser; +import org.sonatype.aether.repository.Authentication; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.RepositoryPolicy; +import org.sonatype.aether.repository.WorkspaceReader; +import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.sonatype.aether.util.graph.manager.ClassicDependencyManager; +import org.sonatype.aether.util.graph.selector.AndDependencySelector; +import org.sonatype.aether.util.graph.selector.ExclusionDependencySelector; +import org.sonatype.aether.util.graph.selector.OptionalDependencySelector; +import org.sonatype.aether.util.graph.selector.ScopeDependencySelector; +import org.sonatype.aether.util.graph.transformer.ChainedDependencyGraphTransformer; +import org.sonatype.aether.util.graph.transformer.NearestVersionConflictResolver; +import org.sonatype.aether.util.graph.transformer.ConflictMarker; +import org.sonatype.aether.util.graph.transformer.JavaDependencyContextRefiner; +import org.sonatype.aether.util.graph.transformer.JavaEffectiveScopeCalculator; +import org.sonatype.aether.util.graph.traverser.FatArtifactTraverser; +import org.sonatype.aether.util.listener.AbstractRepositoryListener; +import org.sonatype.aether.util.repository.ChainedWorkspaceReader; +import org.sonatype.aether.util.repository.DefaultAuthenticationSelector; +import org.sonatype.aether.util.repository.DefaultMirrorSelector; +import org.sonatype.aether.util.repository.DefaultProxySelector; /** * @author Jason van Zyl */ -@Component( role = Maven.class ) +@Component(role = Maven.class) public class DefaultMaven implements Maven { @@ -78,7 +111,6 @@ public class DefaultMaven @Requirement protected ProjectBuilder projectBuilder; - @Requirement private LifecycleStarter lifecycleStarter; @@ -91,6 +123,21 @@ public class DefaultMaven @Requirement private ExecutionEventCatapult eventCatapult; + @Requirement + private ArtifactHandlerManager artifactHandlerManager; + + @Requirement( optional = true, hint = "ide" ) + private WorkspaceReader workspaceRepository; + + @Requirement + private RepositorySystem repoSystem; + + @Requirement + private SettingsDecrypter settingsDecrypter; + + @Requirement + private LegacySupport legacySupport; + public MavenExecutionResult execute( MavenExecutionRequest request ) { MavenExecutionResult result; @@ -113,22 +160,25 @@ public MavenExecutionResult execute( MavenExecutionRequest request ) processResult( new DefaultMavenExecutionResult(), new InternalErrorException( "Internal error: " + e, e ) ); } + finally + { + legacySupport.setSession( null ); + } return result; } - @SuppressWarnings( { "ThrowableInstanceNeverThrown", "ThrowableResultOfMethodCallIgnored" } ) + @SuppressWarnings({"ThrowableInstanceNeverThrown", "ThrowableResultOfMethodCallIgnored"}) private MavenExecutionResult doExecute( MavenExecutionRequest request ) { //TODO: Need a general way to inject standard properties if ( request.getStartTime() != null ) { - request.getSystemProperties().put( "${build.timestamp}", - new SimpleDateFormat( "yyyyMMdd-hhmm" ).format( request.getStartTime() ) ); - } - + request.getSystemProperties().put( "${build.timestamp}", new SimpleDateFormat( "yyyyMMdd-hhmm" ).format( request.getStartTime() ) ); + } + request.setStartTime( new Date() ); - + MavenExecutionResult result = new DefaultMavenExecutionResult(); try @@ -142,10 +192,13 @@ private MavenExecutionResult doExecute( MavenExecutionRequest request ) DelegatingLocalArtifactRepository delegatingLocalArtifactRepository = new DelegatingLocalArtifactRepository( request.getLocalRepository() ); + + request.setLocalRepository( delegatingLocalArtifactRepository ); - request.setLocalRepository( delegatingLocalArtifactRepository ); + DefaultRepositorySystemSession repoSession = (DefaultRepositorySystemSession) newRepositorySession( request ); - MavenSession session = new MavenSession( container, request, result ); + MavenSession session = new MavenSession( container, repoSession, request, result ); + legacySupport.setSession( session ); try { @@ -161,12 +214,14 @@ private MavenExecutionResult doExecute( MavenExecutionRequest request ) eventCatapult.fire( ExecutionEvent.Type.ProjectDiscoveryStarted, session, null ); - //TODO: optimize for the single project or no project + request.getProjectBuildingRequest().setRepositorySession( session.getRepositorySession() ); + //TODO: optimize for the single project or no project + List projects; try { - projects = getProjectsForMavenReactor( request ); + projects = getProjectsForMavenReactor( request ); } catch ( ProjectBuildingException e ) { @@ -176,20 +231,23 @@ private MavenExecutionResult doExecute( MavenExecutionRequest request ) session.setProjects( projects ); result.setTopologicallySortedProjects( session.getProjects() ); - + result.setProject( session.getTopLevelProject() ); try { Map projectMap; projectMap = getProjectMap( session.getProjects() ); - + // Desired order of precedence for local artifact repositories // // Reactor // Workspace // User Local Repository - delegatingLocalArtifactRepository.setBuildReactor( new ReactorArtifactRepository( projectMap ) ); + ReactorReader reactorRepository = new ReactorReader( projectMap ); + + repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorRepository, + repoSession.getWorkspaceReader() ) ); } catch ( org.apache.maven.DuplicateProjectException e ) { @@ -226,7 +284,7 @@ private MavenExecutionResult doExecute( MavenExecutionRequest request ) session.setProjectDependencyGraph( projectDependencyGraph ); } catch ( CycleDetectedException e ) - { + { String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage(); ProjectCycleException error = new ProjectCycleException( message, e ); @@ -261,7 +319,133 @@ private MavenExecutionResult doExecute( MavenExecutionRequest request ) return result; } - @SuppressWarnings( { "ResultOfMethodCallIgnored" } ) + public RepositorySystemSession newRepositorySession( MavenExecutionRequest request ) + { + DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(); + + session.setCache( request.getRepositoryCache() ); + + session.setIgnoreInvalidArtifactDescriptor( true ).setIgnoreMissingArtifactDescriptor( true ); + + session.setUserProps( request.getUserProperties() ); + session.setSystemProps( request.getSystemProperties() ); + session.setConfigProps( request.getSystemProperties() ); + + session.setOffline( request.isOffline() ); + session.setChecksumPolicy( request.getGlobalChecksumPolicy() ); + session.setUpdatePolicy( request.isUpdateSnapshots() ? RepositoryPolicy.UPDATE_POLICY_ALWAYS : null ); + + session.setNotFoundCachingEnabled( !request.isUpdateSnapshots() ); + session.setTransferErrorCachingEnabled( !request.isUpdateSnapshots() ); + + session.setArtifactTypeRegistry( RepositoryUtils.newArtifactTypeRegistry( artifactHandlerManager ) ); + + LocalRepository localRepo = new LocalRepository( request.getLocalRepository().getBasedir() ); + session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( localRepo ) ); + + session.setWorkspaceReader( workspaceRepository ); + + DefaultSettingsDecryptionRequest decrypt = new DefaultSettingsDecryptionRequest(); + decrypt.setProxies( request.getProxies() ); + decrypt.setServers( request.getServers() ); + SettingsDecryptionResult decrypted = settingsDecrypter.decrypt( decrypt ); + + if ( logger.isDebugEnabled() ) + { + for ( SettingsProblem problem : decrypted.getProblems() ) + { + logger.debug( problem.getMessage(), problem.getException() ); + } + } + + DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector(); + for ( Mirror mirror : request.getMirrors() ) + { + mirrorSelector.add( mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, mirror.getMirrorOf(), + mirror.getMirrorOfLayouts() ); + } + session.setMirrorSelector( mirrorSelector ); + + DefaultProxySelector proxySelector = new DefaultProxySelector(); + for ( Proxy proxy : decrypted.getProxies() ) + { + Authentication proxyAuth = new Authentication( proxy.getUsername(), proxy.getPassword() ); + proxySelector.add( new org.sonatype.aether.repository.Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), + proxyAuth ), proxy.getNonProxyHosts() ); + } + session.setProxySelector( proxySelector ); + + DefaultAuthenticationSelector authSelector = new DefaultAuthenticationSelector(); + for ( Server server : decrypted.getServers() ) + { + Authentication auth = + new Authentication( server.getUsername(), server.getPassword(), server.getPrivateKey(), + server.getPassphrase() ); + authSelector.add( server.getId(), auth ); + } + session.setAuthenticationSelector( authSelector ); + + DependencyTraverser depTraverser = new FatArtifactTraverser(); + session.setDependencyTraverser( depTraverser ); + + DependencyManager depManager = new ClassicDependencyManager(); + session.setDependencyManager( depManager ); + + DependencySelector depFilter = + new AndDependencySelector( new ScopeDependencySelector( "test", "provided" ), new OptionalDependencySelector(), + new ExclusionDependencySelector() ); + session.setDependencySelector( depFilter ); + + DependencyGraphTransformer transformer = + new ChainedDependencyGraphTransformer( new ConflictMarker(), new JavaEffectiveScopeCalculator(), + new NearestVersionConflictResolver(), + new JavaDependencyContextRefiner() ); + session.setDependencyGraphTransformer( transformer ); + + session.setTransferListener( request.getTransferListener() ); + + session.setRepositoryListener( new AbstractRepositoryListener() + { + @Override + public void artifactInstalling( RepositoryEvent event ) + { + logger.info( "Installing " + event.getArtifact().getFile() + " to " + event.getFile() ); + } + + @Override + public void metadataInstalling( RepositoryEvent event ) + { + logger.debug( "Installing " + event.getMetadata() + " to " + event.getFile() ); + } + + @Override + public void artifactDescriptorInvalid( RepositoryEvent event ) + { + if ( logger.isDebugEnabled() ) + { + logger.warn( "The POM for " + event.getArtifact() + " is invalid" + + ", transitive dependencies (if any) will not be available: " + + event.getException().getMessage() ); + } + else + { + logger.warn( "The POM for " + event.getArtifact() + " is invalid" + + ", transitive dependencies (if any) will not be available" + + ", enable debug logging for more details" ); + } + } + + @Override + public void artifactDescriptorMissing( RepositoryEvent event ) + { + logger.warn( "The POM for " + event.getArtifact() + " is missing, no dependency information available" ); + } + } ); + + return session; + } + + @SuppressWarnings({"ResultOfMethodCallIgnored"}) private void validateLocalRepository( MavenExecutionRequest request ) throws LocalRepositoryNotAccessibleException { @@ -334,7 +518,7 @@ private MavenExecutionResult processResult( MavenExecutionResult result, Throwab return result; } - + private List getProjectsForMavenReactor( MavenExecutionRequest request ) throws ProjectBuildingException { @@ -352,8 +536,8 @@ private List getProjectsForMavenReactor( MavenExecutionRequest req request.setProjectPresent( false ); return projects; } - - List files = Arrays.asList( request.getPom().getAbsoluteFile() ); + + List files = Arrays.asList( request.getPom().getAbsoluteFile() ); collectProjects( projects, files, request ); return projects; } @@ -405,8 +589,7 @@ private void collectProjects( List projects, List files, Mav { ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest(); - List results = - projectBuilder.build( files, request.isRecursive(), projectBuildingRequest ); + List results = projectBuilder.build( files, request.isRecursive(), projectBuildingRequest ); boolean problems = false; @@ -423,8 +606,7 @@ private void collectProjects( List projects, List files, Mav for ( ModelProblem problem : result.getProblems() ) { String location = ModelProblemUtils.formatLocation( problem, result.getProjectId() ); - logger.warn( problem.getMessage() - + ( StringUtils.isNotEmpty( location ) ? " @ " + location : "" ) ); + logger.warn( problem.getMessage() + ( StringUtils.isNotEmpty( location ) ? " @ " + location : "" ) ); } problems = true; diff --git a/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java index 30a551d25c..c53cb97838 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java @@ -42,7 +42,7 @@ import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; -@Component( role = ProjectDependenciesResolver.class ) +@Component(role = ProjectDependenciesResolver.class) public class DefaultProjectDependenciesResolver implements ProjectDependenciesResolver { @@ -97,15 +97,15 @@ private Set resolveImpl( Collection projects, return resolved; } - if ( ( scopesToCollect == null || scopesToCollect.isEmpty() ) - && ( scopesToResolve == null || scopesToResolve.isEmpty() ) ) + if ( ( scopesToCollect == null || scopesToCollect.isEmpty() ) && + ( scopesToResolve == null || scopesToResolve.isEmpty() ) ) { return resolved; } /* - Logic for transitive global exclusions + Logic for transitve global exclusions List exclusions = new ArrayList(); @@ -126,8 +126,7 @@ private Set resolveImpl( Collection projects, if ( ! exclusions.isEmpty() ) { - filter = new AndArtifactFilter( Arrays.asList( new ArtifactFilter[]{ new ExcludesArtifactFilter( exclusions ), - scopeFilter } ) ); + filter = new AndArtifactFilter( Arrays.asList( new ArtifactFilter[]{ new ExcludesArtifactFilter( exclusions ), scopeFilter } ) ); } else { @@ -141,11 +140,10 @@ private Set resolveImpl( Collection projects, collectionScopeFilter = new CumulativeScopeArtifactFilter( collectionScopeFilter, resolutionScopeFilter ); ArtifactResolutionRequest request = - new ArtifactResolutionRequest().setResolveRoot( false ).setResolveTransitively( true ) - .setCollectionFilter( collectionScopeFilter ).setResolutionFilter( resolutionScopeFilter ) - .setLocalRepository( session.getLocalRepository() ).setOffline( session.isOffline() ) - .setForceUpdate( session.getRequest().isUpdateSnapshots() ).setCache( session.getRepositoryCache() ); - request.setTransferListener( session.getRequest().getTransferListener() ); + new ArtifactResolutionRequest().setResolveRoot( false ).setResolveTransitively( true ).setCollectionFilter( + collectionScopeFilter ).setResolutionFilter( resolutionScopeFilter ).setLocalRepository( + session.getLocalRepository() ).setOffline( session.isOffline() ).setForceUpdate( + session.getRequest().isUpdateSnapshots() ); request.setServers( session.getRequest().getServers() ); request.setMirrors( session.getRequest().getMirrors() ); request.setProxies( session.getRequest().getProxies() ); diff --git a/maven-core/src/main/java/org/apache/maven/ReactorArtifactRepository.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java similarity index 62% rename from maven-core/src/main/java/org/apache/maven/ReactorArtifactRepository.java rename to maven-core/src/main/java/org/apache/maven/ReactorReader.java index dee5e3581e..50ff833bc9 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorArtifactRepository.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -19,39 +19,40 @@ * under the License. */ -import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.LocalArtifactRepository; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.repository.WorkspaceReader; +import org.sonatype.aether.repository.WorkspaceRepository; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; /** - * An implementation of a repository that knows how to search the Maven reactor for artifacts. - * + * An implementation of a workspace reader that knows how to search the Maven reactor for artifacts. + * * @author Jason van Zyl */ -public class ReactorArtifactRepository - extends LocalArtifactRepository +class ReactorReader + implements WorkspaceReader { private Map projectsByGAV; private Map> projectsByGA; - private final int hashCode; + private WorkspaceRepository repository; @SuppressWarnings( { "ConstantConditions" } ) - public ReactorArtifactRepository( Map reactorProjects ) + public ReactorReader( Map reactorProjects ) { projectsByGAV = reactorProjects; - hashCode = ( reactorProjects != null ) ? reactorProjects.keySet().hashCode() : 0; projectsByGA = new HashMap>( reactorProjects.size() * 2 ); for ( MavenProject project : reactorProjects.values() ) @@ -68,35 +69,18 @@ public ReactorArtifactRepository( Map reactorProjects ) projects.add( project ); } - } - @Override - public Artifact find( Artifact artifact ) - { - String projectKey = ArtifactUtils.key( artifact ); - - MavenProject project = projectsByGAV.get( projectKey ); - - if ( project != null ) - { - File file = find( project, artifact ); - if ( file != null ) - { - resolve( artifact, file ); - } - } - - return artifact; + repository = new WorkspaceRepository( "reactor", new HashSet( projectsByGAV.keySet() ) ); } private File find( MavenProject project, Artifact artifact ) { - if ( "pom".equals( artifact.getType() ) ) + if ( "pom".equals( artifact.getExtension() ) ) { return project.getFile(); } - Artifact projectArtifact = findMatchingArtifact( project, artifact ); + org.apache.maven.artifact.Artifact projectArtifact = findMatchingArtifact( project, artifact ); if ( hasArtifactFileFromPackagePhase( projectArtifact ) ) { @@ -125,24 +109,120 @@ else if ( !project.hasCompletedPhase( "package" ) ) return null; } - private boolean hasArtifactFileFromPackagePhase( Artifact projectArtifact ) + private boolean hasArtifactFileFromPackagePhase( org.apache.maven.artifact.Artifact projectArtifact ) { return projectArtifact != null && projectArtifact.getFile() != null && projectArtifact.getFile().exists(); } - private void resolve( Artifact artifact, File file ) + /** + * Tries to resolve the specified artifact from the artifacts of the given project. + * + * @param project The project to try to resolve the artifact from, must not be null. + * @param requestedArtifact The artifact to resolve, must not be null. + * @return The matching artifact from the project or null if not found. + */ + private org.apache.maven.artifact.Artifact findMatchingArtifact( MavenProject project, Artifact requestedArtifact ) { - artifact.setFile( file ); + String requestedRepositoryConflictId = getConflictId( requestedArtifact ); - artifact.setResolved( true ); + org.apache.maven.artifact.Artifact mainArtifact = project.getArtifact(); + if ( requestedRepositoryConflictId.equals( getConflictId( mainArtifact ) ) ) + { + return mainArtifact; + } - artifact.setRepository( this ); + Collection attachedArtifacts = project.getAttachedArtifacts(); + if ( attachedArtifacts != null && !attachedArtifacts.isEmpty() ) + { + for ( org.apache.maven.artifact.Artifact attachedArtifact : attachedArtifacts ) + { + if ( requestedRepositoryConflictId.equals( getConflictId( attachedArtifact ) ) ) + { + return attachedArtifact; + } + } + } + + return null; + } + + /** + * Gets the repository conflict id of the specified artifact. Unlike the dependency conflict id, the repository + * conflict id uses the artifact file extension instead of the artifact type. Hence, the repository conflict id more + * closely reflects the identity of artifacts as perceived by a repository. + * + * @param artifact The artifact, must not be null. + * @return The repository conflict id, never null. + */ + private String getConflictId( org.apache.maven.artifact.Artifact artifact ) + { + StringBuilder buffer = new StringBuilder( 128 ); + buffer.append( artifact.getGroupId() ); + buffer.append( ':' ).append( artifact.getArtifactId() ); + if ( artifact.getArtifactHandler() != null ) + { + buffer.append( ':' ).append( artifact.getArtifactHandler().getExtension() ); + } + else + { + buffer.append( ':' ).append( artifact.getType() ); + } + if ( artifact.hasClassifier() ) + { + buffer.append( ':' ).append( artifact.getClassifier() ); + } + return buffer.toString(); + } + + private String getConflictId( Artifact artifact ) + { + StringBuilder buffer = new StringBuilder( 128 ); + buffer.append( artifact.getGroupId() ); + buffer.append( ':' ).append( artifact.getArtifactId() ); + buffer.append( ':' ).append( artifact.getExtension() ); + if ( artifact.getClassifier().length() > 0 ) + { + buffer.append( ':' ).append( artifact.getClassifier() ); + } + return buffer.toString(); + } + + /** + * Determines whether the specified artifact refers to test classes. + * + * @param artifact The artifact to check, must not be {@code null}. + * @return {@code true} if the artifact refers to test classes, {@code false} otherwise. + */ + private static boolean isTestArtifact( Artifact artifact ) + { + if ( "test-jar".equals( artifact.getProperty( "type", "" ) ) ) + { + return true; + } + else if ( "jar".equals( artifact.getExtension() ) && "tests".equals( artifact.getClassifier() ) ) + { + return true; + } + return false; + } + + public File findArtifact( Artifact artifact ) + { + String projectKey = artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getVersion(); + + MavenProject project = projectsByGAV.get( projectKey ); + + if ( project != null ) + { + return find( project, artifact ); + } + + return null; } - @Override public List findVersions( Artifact artifact ) { - String key = ArtifactUtils.versionlessKey( artifact ); + String key = artifact.getGroupId() + ':' + artifact.getArtifactId(); List projects = projectsByGA.get( key ); if ( projects == null || projects.isEmpty() ) @@ -163,148 +243,9 @@ public List findVersions( Artifact artifact ) return Collections.unmodifiableList( versions ); } - @Override - public String getId() + public WorkspaceRepository getRepository() { - return "reactor"; - } - - @Override - public boolean hasLocalMetadata() - { - return false; - } - - /** - * Tries to resolve the specified artifact from the artifacts of the given project. - * - * @param project The project to try to resolve the artifact from, must not be null. - * @param requestedArtifact The artifact to resolve, must not be null. - * @return The matching artifact from the project or null if not found. - */ - private Artifact findMatchingArtifact( MavenProject project, Artifact requestedArtifact ) - { - String requestedDependencyConflictId = requestedArtifact.getDependencyConflictId(); - - // check for match with project's main artifact by dependency conflict id - Artifact mainArtifact = project.getArtifact(); - if ( requestedDependencyConflictId.equals( mainArtifact.getDependencyConflictId() ) ) - { - return mainArtifact; - } - - String requestedRepositoryConflictId = getRepositoryConflictId( requestedArtifact ); - - // check for match with project's main artifact by repository conflict id - if ( requestedRepositoryConflictId.equals( getRepositoryConflictId( mainArtifact ) ) ) - { - return mainArtifact; - } - - // check for match with one of the attached artifacts - Collection attachedArtifacts = project.getAttachedArtifacts(); - if ( attachedArtifacts != null && !attachedArtifacts.isEmpty() ) - { - // first try matching by dependency conflict id - for ( Artifact attachedArtifact : attachedArtifacts ) - { - if ( requestedDependencyConflictId.equals( attachedArtifact.getDependencyConflictId() ) ) - { - return attachedArtifact; - } - } - - // next try matching by repository conflict id - for ( Artifact attachedArtifact : attachedArtifacts ) - { - if ( requestedRepositoryConflictId.equals( getRepositoryConflictId( attachedArtifact ) ) ) - { - return attachedArtifact; - } - } - } - - return null; - } - - /** - * Gets the repository conflict id of the specified artifact. Unlike the dependency conflict id, the repository - * conflict id uses the artifact file extension instead of the artifact type. Hence, the repository conflict id more - * closely reflects the identity of artifacts as perceived by a repository. - * - * @param artifact The artifact, must not be null. - * @return The repository conflict id, never null. - */ - private String getRepositoryConflictId( Artifact artifact ) - { - StringBuilder buffer = new StringBuilder( 128 ); - buffer.append( artifact.getGroupId() ); - buffer.append( ':' ).append( artifact.getArtifactId() ); - if ( artifact.getArtifactHandler() != null ) - { - buffer.append( ':' ).append( artifact.getArtifactHandler().getExtension() ); - } - else - { - buffer.append( ':' ).append( artifact.getType() ); - } - if ( artifact.hasClassifier() ) - { - buffer.append( ':' ).append( artifact.getClassifier() ); - } - return buffer.toString(); - } - - /** - * Determines whether the specified artifact refers to test classes. - * - * @param artifact The artifact to check, must not be {@code null}. - * @return {@code true} if the artifact refers to test classes, {@code false} otherwise. - */ - private static boolean isTestArtifact( Artifact artifact ) - { - if ( "test-jar".equals( artifact.getType() ) ) - { - return true; - } - else if ( "jar".equals( artifact.getType() ) && "tests".equals( artifact.getClassifier() ) ) - { - return true; - } - return false; - } - - @Override - public int hashCode() - { - return hashCode; - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - if ( obj == null ) - { - return false; - } - if ( getClass() != obj.getClass() ) - { - return false; - } - - ReactorArtifactRepository other = (ReactorArtifactRepository) obj; - - return eq( projectsByGAV.keySet(), other.projectsByGAV.keySet() ); - } - - @Override - public boolean isProjectAware() - { - return true; + return repository; } } diff --git a/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java b/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java new file mode 100644 index 0000000000..9f0efd4f4b --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java @@ -0,0 +1,325 @@ +package org.apache.maven; + +/* + * 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. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.DefaultArtifactHandler; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.artifact.ArtifactType; +import org.sonatype.aether.artifact.ArtifactTypeRegistry; +import org.sonatype.aether.graph.Dependency; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.graph.Exclusion; +import org.sonatype.aether.repository.Authentication; +import org.sonatype.aether.repository.Proxy; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.RepositoryPolicy; +import org.sonatype.aether.util.artifact.ArtifactProperties; +import org.sonatype.aether.util.artifact.DefaultArtifact; +import org.sonatype.aether.util.artifact.DefaultArtifactType; + +/** + * Warning: This is an internal utility class that is only public for technical reasons, it is not part + * of the public API. In particular, this class can be changed or deleted without prior notice. + * + * @author Benjamin Bentmann + */ +public class RepositoryUtils +{ + + private static String nullify( String string ) + { + return ( string == null || string.length() <= 0 ) ? null : string; + } + + private static org.apache.maven.artifact.Artifact toArtifact( Dependency dependency ) + { + if ( dependency == null ) + { + return null; + } + + org.apache.maven.artifact.Artifact result = toArtifact( dependency.getArtifact() ); + result.setScope( dependency.getScope() ); + result.setOptional( dependency.isOptional() ); + + return result; + } + + public static org.apache.maven.artifact.Artifact toArtifact( Artifact artifact ) + { + if ( artifact == null ) + { + return null; + } + + ArtifactHandler handler = newHandler( artifact ); + + /* + * NOTE: From Artifact.hasClassifier(), an empty string and a null both denote "no classifier". However, some + * plugins only check for null, so be sure to nullify an empty classifier. + */ + org.apache.maven.artifact.Artifact result = + new org.apache.maven.artifact.DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), + artifact.getVersion(), null, + artifact.getProperty( ArtifactProperties.TYPE, + artifact.getExtension() ), + nullify( artifact.getClassifier() ), handler ); + + result.setFile( artifact.getFile() ); + result.setResolved( artifact.getFile() != null ); + + List trail = new ArrayList( 1 ); + trail.add( result.getId() ); + result.setDependencyTrail( trail ); + + return result; + } + + public static void toArtifacts( Collection artifacts, + Collection nodes, List trail, + DependencyFilter filter ) + { + for ( DependencyNode node : nodes ) + { + org.apache.maven.artifact.Artifact artifact = toArtifact( node.getDependency() ); + + List nodeTrail = new ArrayList( trail.size() + 1 ); + nodeTrail.addAll( trail ); + nodeTrail.add( artifact.getId() ); + + if ( filter == null || filter.accept( node, Collections. emptyList() ) ) + { + artifact.setDependencyTrail( nodeTrail ); + artifacts.add( artifact ); + } + + toArtifacts( artifacts, node.getChildren(), nodeTrail, filter ); + } + } + + public static Artifact toArtifact( org.apache.maven.artifact.Artifact artifact ) + { + if ( artifact == null ) + { + return null; + } + + String version = artifact.getVersion(); + if ( version == null && artifact.getVersionRange() != null ) + { + version = artifact.getVersionRange().toString(); + } + + Map props = null; + if ( org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) ) + { + props = Collections.singletonMap( ArtifactProperties.LACKS_DESCRIPTOR, Boolean.TRUE.toString() ); + } + + Artifact result = + new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(), + artifact.getArtifactHandler().getExtension(), version, props, + newArtifactType( artifact.getType(), artifact.getArtifactHandler() ) ); + result = result.setFile( artifact.getFile() ); + + return result; + } + + public static Dependency toDependency( org.apache.maven.artifact.Artifact artifact, + Collection exclusions ) + { + if ( artifact == null ) + { + return null; + } + + 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 ) ); + } + } + + 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; + } + + public static RemoteRepository toRepo( ArtifactRepository repo ) + { + RemoteRepository result = null; + if ( repo != null ) + { + result = new RemoteRepository( repo.getId(), repo.getLayout().getId(), repo.getUrl() ); + result.setPolicy( true, toPolicy( repo.getSnapshots() ) ); + result.setPolicy( false, toPolicy( repo.getReleases() ) ); + result.setAuthentication( toAuthentication( repo.getAuthentication() ) ); + result.setProxy( toProxy( repo.getProxy() ) ); + } + return result; + } + + private static RepositoryPolicy toPolicy( ArtifactRepositoryPolicy policy ) + { + RepositoryPolicy result = null; + if ( policy != null ) + { + result = new RepositoryPolicy( policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy() ); + } + return result; + } + + private static Authentication toAuthentication( org.apache.maven.artifact.repository.Authentication auth ) + { + Authentication result = null; + if ( auth != null ) + { + result = new Authentication( auth.getUsername(), auth.getPassword() ); + } + return result; + } + + private static Proxy toProxy( org.apache.maven.repository.Proxy proxy ) + { + Proxy result = null; + if ( proxy != null ) + { + Authentication auth = new Authentication( proxy.getUserName(), proxy.getPassword() ); + result = new Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), auth ); + } + return result; + } + + public static ArtifactHandler newHandler( Artifact artifact ) + { + String type = artifact.getProperty( ArtifactProperties.TYPE, artifact.getExtension() ); + DefaultArtifactHandler handler = new DefaultArtifactHandler( type ); + handler.setExtension( artifact.getExtension() ); + handler.setLanguage( artifact.getProperty( ArtifactProperties.LANGUAGE, null ) ); + handler.setAddedToClasspath( Boolean.parseBoolean( artifact.getProperty( ArtifactProperties.CONSTITUTES_BUILD_PATH, + "" ) ) ); + handler.setIncludesDependencies( Boolean.parseBoolean( artifact.getProperty( ArtifactProperties.INCLUDES_DEPENDENCIES, + "" ) ) ); + return handler; + } + + public static ArtifactType newArtifactType( String id, ArtifactHandler handler ) + { + return new DefaultArtifactType( id, handler.getExtension(), handler.getClassifier(), handler.getLanguage(), + handler.isAddedToClasspath(), handler.isIncludesDependencies() ); + } + + public static Dependency toDependency( org.apache.maven.model.Dependency dependency, + ArtifactTypeRegistry stereotypes ) + { + ArtifactType stereotype = stereotypes.get( dependency.getType() ); + if ( stereotype == null ) + { + stereotype = new DefaultArtifactType( dependency.getType() ); + } + + boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0; + + Map props = null; + if ( system ) + { + props = Collections.singletonMap( ArtifactProperties.LACKS_DESCRIPTOR, Boolean.TRUE.toString() ); + } + + Artifact artifact = + new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null, + dependency.getVersion(), props, stereotype ); + + if ( system ) + { + artifact = artifact.setFile( new File( dependency.getSystemPath() ) ); + } + + List exclusions = new ArrayList( dependency.getExclusions().size() ); + for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() ) + { + exclusions.add( toExclusion( exclusion ) ); + } + + Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions ); + + return result; + } + + private static Exclusion toExclusion( org.apache.maven.model.Exclusion exclusion ) + { + return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" ); + } + + public static ArtifactTypeRegistry newArtifactTypeRegistry( ArtifactHandlerManager handlerManager ) + { + return new MavenArtifactTypeRegistry( handlerManager ); + } + + static class MavenArtifactTypeRegistry + implements ArtifactTypeRegistry + { + + private final ArtifactHandlerManager handlerManager; + + public MavenArtifactTypeRegistry( ArtifactHandlerManager handlerManager ) + { + this.handlerManager = handlerManager; + } + + public ArtifactType get( String stereotypeId ) + { + ArtifactHandler handler = handlerManager.getArtifactHandler( stereotypeId ); + return newArtifactType( stereotypeId, handler ); + } + + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java b/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java index 3e66a2255e..dd5087498b 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java @@ -64,6 +64,11 @@ public String getExtension() return extension; } + public void setExtension( String extension ) + { + this.extension = extension; + } + public String getType() { return type; @@ -97,6 +102,11 @@ public boolean isIncludesDependencies() return includesDependencies; } + public void setIncludesDependencies( boolean includesDependencies ) + { + this.includesDependencies = includesDependencies; + } + public String getLanguage() { if ( language == null ) @@ -107,8 +117,19 @@ public String getLanguage() return language; } + public void setLanguage( String language ) + { + this.language = language; + } + public boolean isAddedToClasspath() { return addedToClasspath; } + + public void setAddedToClasspath( boolean addedToClasspath ) + { + this.addedToClasspath = addedToClasspath; + } + } diff --git a/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java b/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java index 6139b66692..16cdeffbf2 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java @@ -24,11 +24,10 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.ArtifactTransferListener; /** * Collects basic settings to access the repository system. - * + * * @author Benjamin Bentmann */ public class DefaultRepositoryRequest @@ -43,10 +42,6 @@ public class DefaultRepositoryRequest private List remoteRepositories; - private RepositoryCache cache; - - private ArtifactTransferListener transferListener; - /** * Creates an empty repository request. */ @@ -57,7 +52,7 @@ public DefaultRepositoryRequest() /** * Creates a shallow copy of the specified repository request. - * + * * @param repositoryRequest The repository request to copy from, must not be {@code null}. */ public DefaultRepositoryRequest( RepositoryRequest repositoryRequest ) @@ -65,16 +60,13 @@ public DefaultRepositoryRequest( RepositoryRequest repositoryRequest ) setLocalRepository( repositoryRequest.getLocalRepository() ); setRemoteRepositories( repositoryRequest.getRemoteRepositories() ); setOffline( repositoryRequest.isOffline() ); - setCache( repositoryRequest.getCache() ); setForceUpdate( repositoryRequest.isForceUpdate() ); - setTransferListener( repositoryRequest.getTransferListener() ); } public static RepositoryRequest getRepositoryRequest( MavenSession session, MavenProject project ) { RepositoryRequest request = new DefaultRepositoryRequest(); - request.setCache( session.getRepositoryCache() ); request.setLocalRepository( session.getLocalRepository() ); if ( project != null ) { @@ -82,7 +74,6 @@ public static RepositoryRequest getRepositoryRequest( MavenSession session, Mave } request.setOffline( session.isOffline() ); request.setForceUpdate( session.getRequest().isUpdateSnapshots() ); - request.setTransferListener( session.getRequest().getTransferListener() ); return request; } @@ -140,28 +131,4 @@ public DefaultRepositoryRequest setRemoteRepositories( List return this; } - public RepositoryCache getCache() - { - return cache; - } - - public DefaultRepositoryRequest setCache( RepositoryCache cache ) - { - this.cache = cache; - - return this; - } - - public ArtifactTransferListener getTransferListener() - { - return transferListener; - } - - public DefaultRepositoryRequest setTransferListener( ArtifactTransferListener transferListener ) - { - this.transferListener = transferListener; - - return this; - } - } diff --git a/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java b/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java index eb0aa28c7e..8fd5b08e86 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java @@ -25,6 +25,7 @@ * * @author Benjamin Bentmann */ +@Deprecated public interface RepositoryCache { diff --git a/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java b/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java index a355d251f0..870e4f683a 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java @@ -21,8 +21,6 @@ import java.util.List; -import org.apache.maven.repository.ArtifactTransferListener; - /** * Collects basic settings to access the repository system. * @@ -94,34 +92,4 @@ public interface RepositoryRequest */ RepositoryRequest setRemoteRepositories( List remoteRepositories ); - /** - * Gets the repository cache to use. - * - * @return The repository cache to use or {@code null} if none. - */ - RepositoryCache getCache(); - - /** - * Sets the repository cache to use. - * - * @param cache The repository cache to use, may be {@code null}. - * @return This request, never {@code null}. - */ - RepositoryRequest setCache( RepositoryCache cache ); - - /** - * Gets the listener to notify of transfer events. - * - * @return The transfer listener or {@code null} if none. - */ - ArtifactTransferListener getTransferListener(); - - /** - * Sets the listener to notify of transfer events. - * - * @param transferListener The transfer listener to notify, may be {@code null}. - * @return This request, never {@code null}. - */ - RepositoryRequest setTransferListener( ArtifactTransferListener transferListener ); - } diff --git a/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java b/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java index 9720254c45..4b84ba178d 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java @@ -29,7 +29,6 @@ import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.repository.ArtifactTransferListener; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; @@ -55,8 +54,6 @@ public class ArtifactResolutionRequest private List remoteRepositories; - private RepositoryCache cache; - private ArtifactFilter collectionFilter; private ArtifactFilter resolutionFilter; @@ -66,8 +63,6 @@ public class ArtifactResolutionRequest // This is like a filter but overrides all transitive versions private Map managedVersionMap; - - private ArtifactTransferListener transferListener; private boolean resolveRoot = true; @@ -92,10 +87,8 @@ public ArtifactResolutionRequest( RepositoryRequest request ) { setLocalRepository( request.getLocalRepository() ); setRemoteRepositories( request.getRemoteRepositories() ); - setCache( request.getCache() ); setOffline( request.isOffline() ); setForceUpdate( request.isForceUpdate() ); - setTransferListener( request.getTransferListener() ); } public Artifact getArtifact() @@ -237,17 +230,6 @@ public boolean isResolveTransitively() { return resolveTransitively; } - - public ArtifactTransferListener getTransferListener() - { - return transferListener; - } - - public ArtifactResolutionRequest setTransferListener( ArtifactTransferListener transferListener ) - { - this.transferListener = transferListener; - return this; - } public String toString() { @@ -263,13 +245,11 @@ public String toString() public RepositoryCache getCache() { - return cache; + return null; } public ArtifactResolutionRequest setCache( RepositoryCache cache ) { - this.cache = cache; - return this; } diff --git a/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java b/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java index 8c482a9f92..e79fa9d20d 100644 --- a/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java +++ b/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java @@ -21,7 +21,7 @@ import java.io.File; -import org.apache.maven.artifact.Artifact; +import org.sonatype.aether.artifact.Artifact; /** * @author Benjamin Bentmann @@ -49,12 +49,12 @@ public String getArtifactId() public String getType() { - return artifact.getType(); + return artifact.getExtension(); } public String getClassifier() { - return artifact.hasClassifier() ? artifact.getClassifier() : ""; + return artifact.getClassifier(); } public String getVersion() @@ -70,7 +70,7 @@ public File getFile() @Override public String toString() { - return artifact.getId(); + return artifact.toString(); } } diff --git a/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java b/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java index 61867a4dbf..bca8b3fa1d 100644 --- a/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java +++ b/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java @@ -21,10 +21,10 @@ import java.util.List; -import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.sonatype.aether.artifact.Artifact; /** * Manages the class realms used by Maven. Warning: This is an internal utility interface that is only diff --git a/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java b/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java index 71d3f0c4b8..0127550d85 100644 --- a/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java +++ b/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java @@ -28,7 +28,6 @@ import java.util.Random; import java.util.Set; -import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.classrealm.ClassRealmRequest.RealmType; import org.apache.maven.model.Model; @@ -43,11 +42,12 @@ import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; +import org.sonatype.aether.artifact.Artifact; /** * Manages the class realms used by Maven. Warning: This is an internal utility class that is only - * public for technical reasons, it is not part of the public API. In particular, this interface can be changed or - * deleted without prior notice. + * public for technical reasons, it is not part of the public API. In particular, this class can be changed or deleted + * without prior notice. * * @author Benjamin Bentmann */ @@ -133,7 +133,7 @@ private ClassRealm createRealm( String baseRealmId, RealmType type, ClassLoader { for ( Artifact artifact : artifacts ) { - artifactIds.add( artifact.getId() ); + artifactIds.add( getId( artifact ) ); if ( artifact.getFile() != null ) { constituents.add( new ArtifactClassRealmConstituent( artifact ) ); @@ -260,6 +260,9 @@ private void importMavenApi( ClassRealm importingRealm ) // maven-* importingRealm.importFrom( coreRealm, "org.apache.maven" ); + // aether + importingRealm.importFrom( coreRealm, "org.sonatype.aether" ); + // plexus-classworlds importingRealm.importFrom( coreRealm, "org.codehaus.plexus.classworlds" ); @@ -334,11 +337,21 @@ private static String getKey( Plugin plugin, boolean extension ) + version; } + private static String getId( Artifact artifact ) + { + return getId( artifact.getGroupId(), artifact.getArtifactId(), artifact.getExtension(), artifact.getClassifier(), + artifact.getBaseVersion() ); + } + private static String getId( ClassRealmConstituent constituent ) { - return constituent.getGroupId() + ':' + constituent.getArtifactId() + ':' + constituent.getType() - + ( StringUtils.isNotEmpty( constituent.getClassifier() ) ? ':' + constituent.getClassifier() : "" ) + ':' - + constituent.getVersion(); + return getId( constituent.getGroupId(), constituent.getArtifactId(), constituent.getType(), + constituent.getClassifier(), constituent.getVersion() ); + } + + private static String getId( String gid, String aid, String type, String cls, String ver ) + { + return gid + ':' + aid + ':' + type + ( StringUtils.isNotEmpty( cls ) ? ':' + cls : "" ) + ':' + ver; } private List getDelegates() diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java index 6965160f94..96ec958b4d 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java @@ -26,14 +26,15 @@ import java.util.Properties; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.model.Profile; import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.repository.ArtifactTransferListener; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; +import org.sonatype.aether.RepositoryCache; +import org.sonatype.aether.transfer.TransferListener; +import org.sonatype.aether.util.DefaultRepositoryCache; /** * @author Jason van Zyl @@ -42,7 +43,7 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest { - private RepositoryCache repositoryCache = new SessionRepositoryCache(); + private RepositoryCache repositoryCache = new DefaultRepositoryCache(); private ArtifactRepository localRepository; @@ -110,7 +111,7 @@ public class DefaultMavenExecutionRequest private List inactiveProfiles; - private ArtifactTransferListener transferListener; + private TransferListener transferListener; private int loggingLevel = LOGGING_LEVEL_INFO; @@ -350,7 +351,7 @@ public List getInactiveProfiles() return inactiveProfiles; } - public ArtifactTransferListener getTransferListener() + public TransferListener getTransferListener() { return transferListener; } @@ -592,7 +593,7 @@ public MavenExecutionRequest setInteractiveMode( boolean interactive ) return this; } - public MavenExecutionRequest setTransferListener( ArtifactTransferListener transferListener ) + public MavenExecutionRequest setTransferListener( TransferListener transferListener ) { this.transferListener = transferListener; @@ -953,7 +954,6 @@ public ProjectBuildingRequest getProjectBuildingRequest() projectBuildingRequest.setUserProperties( getUserProperties() ); projectBuildingRequest.setRemoteRepositories( getRemoteRepositories() ); projectBuildingRequest.setPluginArtifactRepositories( getPluginArtifactRepositories() ); - projectBuildingRequest.setRepositoryCache( getRepositoryCache() ); projectBuildingRequest.setOffline( isOffline() ); projectBuildingRequest.setForceUpdate( isUpdateSnapshots() ); projectBuildingRequest.setServers( getServers() ); @@ -964,7 +964,6 @@ public ProjectBuildingRequest getProjectBuildingRequest() projectBuildingRequest.setProfiles( getProfiles() ); projectBuildingRequest.setProcessPlugins( true ); projectBuildingRequest.setBuildStartTime( getStartTime() ); - projectBuildingRequest.setTransferListener( getTransferListener() ); } return projectBuildingRequest; diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java index 24e2b0f18e..5616f38380 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java +++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java @@ -25,7 +25,7 @@ import java.util.List; import java.util.Map; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.project.DependencyResolutionResult; import org.apache.maven.project.MavenProject; /** @author Jason van Zyl */ @@ -36,7 +36,7 @@ public class DefaultMavenExecutionResult private List topologicallySortedProjects; - private ArtifactResolutionResult artifactResolutionResult; + private DependencyResolutionResult dependencyResolutionResult; private List exceptions; @@ -66,14 +66,14 @@ public List getTopologicallySortedProjects() return topologicallySortedProjects; } - public ArtifactResolutionResult getArtifactResolutionResult() + public DependencyResolutionResult getDependencyResolutionResult() { - return artifactResolutionResult; + return dependencyResolutionResult; } - public MavenExecutionResult setArtifactResolutionResult( ArtifactResolutionResult artifactResolutionResult ) + public MavenExecutionResult setDependencyResolutionResult( DependencyResolutionResult dependencyResolutionResult ) { - this.artifactResolutionResult = artifactResolutionResult; + this.dependencyResolutionResult = dependencyResolutionResult; return this; } diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java index ea9795c440..85614210fe 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java @@ -26,14 +26,14 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; -import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.model.Profile; import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.repository.ArtifactTransferListener; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; import org.codehaus.plexus.logging.Logger; +import org.sonatype.aether.RepositoryCache; +import org.sonatype.aether.transfer.TransferListener; /** * @author Jason van Zyl @@ -170,8 +170,8 @@ public interface MavenExecutionRequest boolean isShowErrors(); // Transfer listeners - MavenExecutionRequest setTransferListener( ArtifactTransferListener transferListener ); - ArtifactTransferListener getTransferListener(); + MavenExecutionRequest setTransferListener( TransferListener transferListener ); + TransferListener getTransferListener(); // Logging MavenExecutionRequest setLoggingLevel( int loggingLevel ); diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java index 720f4ce410..15ce3e75d1 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java @@ -21,7 +21,7 @@ import java.util.List; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.project.DependencyResolutionResult; import org.apache.maven.project.MavenProject; /** @@ -35,8 +35,8 @@ public interface MavenExecutionResult MavenExecutionResult setTopologicallySortedProjects( List projects ); List getTopologicallySortedProjects(); - MavenExecutionResult setArtifactResolutionResult( ArtifactResolutionResult result ); - ArtifactResolutionResult getArtifactResolutionResult(); + MavenExecutionResult setDependencyResolutionResult( DependencyResolutionResult result ); + DependencyResolutionResult getDependencyResolutionResult(); // for each exception // - knowing what artifacts are missing 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 3593c919a6..f17be2485f 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 @@ -36,6 +36,7 @@ import org.apache.maven.settings.Settings; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.sonatype.aether.RepositorySystemSession; /** * @author Jason van Zyl @@ -50,6 +51,8 @@ public class MavenSession private MavenExecutionResult result; + private RepositorySystemSession repositorySession; + private final Settings settings; private Properties executionProperties; @@ -115,12 +118,14 @@ public MavenSession( PlexusContainer container, MavenExecutionRequest request, M setProjects( projects ); } - public MavenSession( PlexusContainer container, MavenExecutionRequest request, MavenExecutionResult result ) + public MavenSession( PlexusContainer container, RepositorySystemSession repositorySession, MavenExecutionRequest request, + MavenExecutionResult result ) { this.container = container; this.request = request; this.result = result; this.settings = new SettingsAdapter( request ); + this.repositorySession = repositorySession; } public void setProjects( List projects ) @@ -180,9 +185,10 @@ public Map lookupMap( String role ) return container.lookupMap( role ); } + @Deprecated public RepositoryCache getRepositoryCache() { - return request.getRepositoryCache(); + return null; } public ArtifactRepository getLocalRepository() @@ -277,7 +283,7 @@ public MavenProject getCurrentProject() public ProjectBuildingRequest getProjectBuildingRequest() { - return request.getProjectBuildingRequest(); + return request.getProjectBuildingRequest().setRepositorySession( getRepositorySession() ); } public List getPluginGroups() @@ -382,4 +388,10 @@ public void setParallel( boolean parallel ) { this.parallel = parallel; } + + public RepositorySystemSession getRepositorySession() + { + return repositorySession; + } + } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java index d4d9e3d9fd..7a04b2b4f0 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java @@ -21,14 +21,7 @@ import org.apache.maven.lifecycle.internal.BuilderCommon; import org.apache.maven.lifecycle.internal.ExecutionPlanItem; -import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginNotFoundException; -import org.apache.maven.plugin.PluginResolutionException; -import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; -import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.project.MavenProject; import java.util.ArrayList; @@ -55,9 +48,6 @@ public DefaultSchedules( List schedules ) } public List createExecutionPlanItem( MavenProject mavenProject, List executions ) - throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException, - PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException, - NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException { BuilderCommon.attachToThread( mavenProject ); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java index ec26dbd0de..9777416c5e 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java @@ -1,25 +1,19 @@ +/* + * 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.apache.maven.lifecycle.internal; -/* - * 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. - */ - -import org.apache.maven.artifact.repository.DefaultRepositoryRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.DefaultLifecycles; import org.apache.maven.lifecycle.DefaultSchedules; @@ -147,9 +141,10 @@ private void setupMojoExections( MavenSession session, MavenProject project, if ( mojoDescriptor == null ) { - mojoDescriptor = pluginManager.getMojoDescriptor( mojoExecution.getPlugin(), mojoExecution.getGoal(), - DefaultRepositoryRequest.getRepositoryRequest( - session, project ) ); + mojoDescriptor = + pluginManager.getMojoDescriptor( mojoExecution.getPlugin(), mojoExecution.getGoal(), + project.getRemotePluginRepositories(), + session.getRepositorySession() ); mojoExecution.setMojoDescriptor( mojoDescriptor ); } @@ -251,10 +246,11 @@ private Map> calculateLifecycleMappings( MavenSessio if ( lifecycle == null ) { - throw new LifecyclePhaseNotFoundException( "Unknown lifecycle phase \"" + lifecyclePhase - + "\". You must specify a valid lifecycle phase" + " or a goal in the format : or" - + " :[:]:. Available lifecycle phases are: " - + defaultLifeCycles.getLifecyclePhaseList() + ".", lifecyclePhase ); + throw new LifecyclePhaseNotFoundException( + "Unknown lifecycle phase \"" + lifecyclePhase + "\". You must specify a valid lifecycle phase" + + " or a goal in the format : or" + + " :[:]:. Available lifecycle phases are: " + + defaultLifeCycles.getLifecyclePhaseList() + ".", lifecyclePhase ); } /* @@ -309,9 +305,8 @@ private Map> calculateLifecycleMappings( MavenSessio for ( String goal : execution.getGoals() ) { MojoDescriptor mojoDescriptor = - pluginManager.getMojoDescriptor( plugin, goal, - DefaultRepositoryRequest.getRepositoryRequest( session, - project ) ); + pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(), + session.getRepositorySession() ); Map> phaseBindings = mappings.get( mojoDescriptor.getPhase() ); if ( phaseBindings != null ) @@ -464,8 +459,8 @@ private void finalizeMojoConfiguration( MojoExecution mojoExecution ) { parameterConfiguration = new Xpp3Dom( parameterConfiguration, parameter.getName() ); - if ( StringUtils.isEmpty( parameterConfiguration.getAttribute( "implementation" ) ) - && StringUtils.isNotEmpty( parameter.getImplementation() ) ) + if ( StringUtils.isEmpty( parameterConfiguration.getAttribute( "implementation" ) ) && + StringUtils.isNotEmpty( parameter.getImplementation() ) ) { parameterConfiguration.setAttribute( "implementation", parameter.getImplementation() ); } @@ -488,7 +483,8 @@ public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException { - calculateForkedExecutions( mojoExecution, session, session.getCurrentProject(), new HashSet() ); + calculateForkedExecutions( mojoExecution, session, session.getCurrentProject(), new HashSet() ); + } @@ -556,8 +552,8 @@ private List calculateForkedLifecycle( MojoExecution mojoExecutio { MojoDescriptor forkedMojoDescriptor = pluginManager.getMojoDescriptor( forkedExecution.getPlugin(), forkedExecution.getGoal(), - DefaultRepositoryRequest.getRepositoryRequest( session, - project ) ); + project.getRemotePluginRepositories(), + session.getRepositorySession() ); forkedExecution.setMojoDescriptor( forkedMojoDescriptor ); } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java index 701258b008..ebc2e843f3 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java @@ -1,39 +1,41 @@ package org.apache.maven.lifecycle.internal; /* - * 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 + * 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 + * 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. + * 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. */ -import org.apache.maven.ProjectDependenciesResolver; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.factory.ArtifactFactory; -import org.apache.maven.artifact.resolver.ArtifactNotFoundException; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; -import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException; import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.MavenExecutionPlan; +import org.apache.maven.project.DefaultDependencyResolutionRequest; +import org.apache.maven.project.DependencyResolutionException; +import org.apache.maven.project.DependencyResolutionResult; import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectDependenciesResolver; import org.apache.maven.project.artifact.InvalidDependencyVersionException; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; +import org.sonatype.aether.graph.Dependency; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.util.filter.AndDependencyFilter; +import org.sonatype.aether.util.filter.ScopeDependencyFilter; import java.util.*; @@ -47,11 +49,12 @@ *

* NOTE: This class is not part of any public api and can be changed or deleted without prior notice. */ -@Component( role = LifecycleDependencyResolver.class ) +@Component(role = LifecycleDependencyResolver.class) public class LifecycleDependencyResolver { + @Requirement - private ProjectDependenciesResolver projectDependenciesResolver; + private ProjectDependenciesResolver dependenciesResolver; @Requirement private Logger logger; @@ -59,14 +62,14 @@ public class LifecycleDependencyResolver @Requirement private ArtifactFactory artifactFactory; - @SuppressWarnings( { "UnusedDeclaration" } ) + @SuppressWarnings({"UnusedDeclaration"}) public LifecycleDependencyResolver() { } public LifecycleDependencyResolver( ProjectDependenciesResolver projectDependenciesResolver, Logger logger ) { - this.projectDependenciesResolver = projectDependenciesResolver; + this.dependenciesResolver = projectDependenciesResolver; this.logger = logger; } @@ -136,87 +139,112 @@ private void resolveProjectDependencies( MavenProject project, Collection artifacts = - getProjectDependencies( project, scopesToCollect, scopesToResolve, session, aggregating, - projectArtifacts ); + getDependencies( project, scopesToCollect, scopesToResolve, session, aggregating, projectArtifacts ); project.setResolvedArtifacts( artifacts ); + + Map map = new HashMap(); + for ( Artifact artifact : artifacts ) + { + map.put( artifact.getId(), artifact ); + } + for ( Artifact artifact : project.getDependencyArtifacts() ) + { + if ( artifact.getFile() == null ) + { + Artifact resolved = map.get( artifact.getId() ); + if ( resolved != null ) + { + artifact.setFile( resolved.getFile() ); + artifact.setDependencyTrail( resolved.getDependencyTrail() ); + artifact.setResolvedVersion( resolved.getVersion() ); + artifact.setResolved( true ); + } + } + } } - private Set getProjectDependencies( MavenProject project, Collection scopesToCollect, - Collection scopesToResolve, MavenSession session, - boolean aggregating, Set projectArtifacts ) + private Set getDependencies( MavenProject project, Collection scopesToCollect, + Collection scopesToResolve, MavenSession session, + boolean aggregating, Set projectArtifacts ) throws LifecycleExecutionException { - Set artifacts; + if ( scopesToCollect == null ) + { + scopesToCollect = Collections.emptySet(); + } + if ( scopesToResolve == null ) + { + scopesToResolve = Collections.emptySet(); + } + + if ( scopesToCollect.isEmpty() && scopesToResolve.isEmpty() ) + { + return new LinkedHashSet(); + } + + scopesToCollect = new HashSet( scopesToCollect ); + scopesToCollect.addAll( scopesToResolve ); + + DependencyFilter collectionFilter = new ScopeDependencyFilter( null, negate( scopesToCollect ) ); + DependencyFilter resolutionFilter = new ScopeDependencyFilter( null, negate( scopesToResolve ) ); + resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, resolutionFilter ); + resolutionFilter = + AndDependencyFilter.newInstance( resolutionFilter, new ReactorDependencyFilter( projectArtifacts ) ); + + DependencyResolutionResult result; try { - try + DefaultDependencyResolutionRequest request = + new DefaultDependencyResolutionRequest( project, session.getRepositorySession() ); + request.setResolutionFilter( resolutionFilter ); + + result = dependenciesResolver.resolve( request ); + } + catch ( DependencyResolutionException e ) + { + result = e.getResult(); + + /* + * MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator + * plugins that require dependency resolution although they usually run in phases of the build where project + * artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare". + */ + if ( aggregating && areAllDependenciesInReactor( session.getProjects(), result.getUnresolvedDependencies() ) ) { - artifacts = projectDependenciesResolver.resolve( project , scopesToCollect, - scopesToResolve, session, projectArtifacts ); + logger.warn( "The following dependencies could not be resolved at this point of the build" + + " but seem to be part of the reactor:" ); + + for ( Dependency dependency : result.getUnresolvedDependencies() ) + { + logger.warn( "o " + dependency ); + } + + logger.warn( "Try running the build up to the lifecycle phase \"package\"" ); } - catch ( MultipleArtifactsNotFoundException e ) + else { - /* - * MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator - * plugins that require dependency resolution although they usually run in phases of the build where - * project artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare". - */ - artifacts = handleException( session, aggregating, e ); + throw new LifecycleExecutionException( null, project, e ); } - - return artifacts; - } - catch ( ArtifactResolutionException e ) - { - throw new LifecycleExecutionException( null, project, e ); - } - catch ( ArtifactNotFoundException e ) - { - throw new LifecycleExecutionException( null, project, e ); } - } - - - private Set handleException( MavenSession session, boolean aggregating, - MultipleArtifactsNotFoundException e ) - throws MultipleArtifactsNotFoundException - { - Set artifacts; - /* - * MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator - * plugins that require dependency resolution although they usually run in phases of the build where project - * artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare". - */ - if ( aggregating && areAllArtifactsInReactor( session.getProjects(), e.getMissingArtifacts() ) ) + Set artifacts = new LinkedHashSet(); + if ( result.getDependencyGraph() != null && !result.getDependencyGraph().getChildren().isEmpty() ) { - logger.warn( "The following artifacts could not be resolved at this point of the build" - + " but seem to be part of the reactor:" ); - - for ( Artifact artifact : e.getMissingArtifacts() ) - { - logger.warn( "o " + artifact.getId() ); - } - - logger.warn( "Try running the build up to the lifecycle phase \"package\"" ); - - artifacts = new LinkedHashSet( e.getResolvedArtifacts() ); - } - else - { - throw e; + RepositoryUtils.toArtifacts( artifacts, result.getDependencyGraph().getChildren(), + Collections.singletonList( project.getArtifact().getId() ), collectionFilter ); } return artifacts; } - private boolean areAllArtifactsInReactor( Collection projects, Collection artifacts ) + private boolean areAllDependenciesInReactor( Collection projects, Collection dependencies ) { Set projectKeys = getReactorProjectKeys( projects ); - for ( Artifact artifact : artifacts ) + for ( Dependency dependency : dependencies ) { - String key = ArtifactUtils.key( artifact ); + org.sonatype.aether.artifact.Artifact a = dependency.getArtifact(); + String key = ArtifactUtils.key( a.getGroupId(), a.getArtifactId(), a.getVersion() ); if ( !projectKeys.contains( key ) ) { return false; @@ -237,4 +265,73 @@ private Set getReactorProjectKeys( Collection projects ) return projectKeys; } + private Collection negate( Collection scopes ) + { + Collection result = new HashSet(); + Collections.addAll( result, "system", "compile", "provided", "runtime", "test" ); + + for ( String scope : scopes ) + { + if ( "compile".equals( scope ) ) + { + result.remove( "compile" ); + result.remove( "system" ); + result.remove( "provided" ); + } + else if ( "runtime".equals( scope ) ) + { + result.remove( "compile" ); + result.remove( "runtime" ); + } + else if ( "compile+runtime".equals( scope ) ) + { + result.remove( "compile" ); + result.remove( "system" ); + result.remove( "provided" ); + result.remove( "runtime" ); + } + else if ( "runtime+system".equals( scope ) ) + { + result.remove( "compile" ); + result.remove( "system" ); + result.remove( "runtime" ); + } + else if ( "test".equals( scope ) ) + { + result.clear(); + } + } + + return result; + } + + private static class ReactorDependencyFilter + implements DependencyFilter + { + + private Set keys = new HashSet(); + + public ReactorDependencyFilter( Collection artifacts ) + { + for ( Artifact artifact : artifacts ) + { + String key = ArtifactUtils.key( artifact ); + keys.add( key ); + } + } + + public boolean accept( DependencyNode node, List parents ) + { + Dependency dependency = node.getDependency(); + if ( dependency != null ) + { + org.sonatype.aether.artifact.Artifact a = dependency.getArtifact(); + String key = ArtifactUtils.key( a.getGroupId(), a.getArtifactId(), a.getVersion() ); + return !keys.contains( key ); + } + return false; + } + + } + } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java index 00d44553bb..d9984f2a3a 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java @@ -66,7 +66,9 @@ public void resolveMissingPluginVersions( MavenProject project, MavenSession ses { if ( plugin.getVersion() == null ) { - PluginVersionRequest request = new DefaultPluginVersionRequest( plugin, session ); + PluginVersionRequest request = + new DefaultPluginVersionRequest( plugin, session.getRepositorySession(), + project.getRemotePluginRepositories() ); plugin.setVersion( pluginVersionResolver.resolve( request ).getVersion() ); } versions.put( plugin.getKey(), plugin.getVersion() ); @@ -82,7 +84,9 @@ public void resolveMissingPluginVersions( MavenProject project, MavenSession ses plugin.setVersion( versions.get( plugin.getKey() ) ); if ( plugin.getVersion() == null ) { - PluginVersionRequest request = new DefaultPluginVersionRequest( plugin, session ); + PluginVersionRequest request = + new DefaultPluginVersionRequest( plugin, session.getRepositorySession(), + project.getRemotePluginRepositories() ); plugin.setVersion( pluginVersionResolver.resolve( request ).getVersion() ); } } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java index d3ff207568..33ad2d214c 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java @@ -19,8 +19,6 @@ * under the License. */ -import org.apache.maven.artifact.repository.DefaultRepositoryRequest; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.model.Plugin; @@ -202,17 +200,16 @@ else if ( numTokens == 2 ) injectPluginDeclarationFromProject( plugin, project ); - RepositoryRequest repositoryRequest = DefaultRepositoryRequest.getRepositoryRequest( session, project ); - // If there is no version to be found then we need to look in the repository metadata for // this plugin and see what's specified as the latest release. // if ( plugin.getVersion() == null ) { - resolvePluginVersion( plugin, repositoryRequest ); + resolvePluginVersion( plugin, session, project ); } - return pluginManager.getMojoDescriptor( plugin, goal, repositoryRequest ); + return pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(), + session.getRepositorySession() ); } // TODO: take repo mans into account as one may be aggregating prefixes of many @@ -234,10 +231,12 @@ public Plugin findPluginForPrefix( String prefix, MavenSession session ) return plugin; } - private void resolvePluginVersion( Plugin plugin, RepositoryRequest repositoryRequest ) + private void resolvePluginVersion( Plugin plugin, MavenSession session, MavenProject project ) throws PluginVersionResolutionException { - PluginVersionRequest versionRequest = new DefaultPluginVersionRequest( plugin, repositoryRequest ); + PluginVersionRequest versionRequest = + new DefaultPluginVersionRequest( plugin, session.getRepositorySession(), + project.getRemotePluginRepositories() ); plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() ); } diff --git a/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java b/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java index cd38e43eca..0a20f5ae3d 100644 --- a/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java +++ b/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java @@ -27,7 +27,7 @@ import java.util.List; import java.util.Map; -import org.apache.maven.lifecycle.LifecycleExecutor; +import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer; import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; @@ -54,7 +54,7 @@ public class DefaultLifecycleBindingsInjector private LifecycleBindingsMerger merger = new LifecycleBindingsMerger(); @Requirement - private LifecycleExecutor lifecycle; + private LifeCyclePluginAnalyzer lifecycle; public void injectLifecycleBindings( Model model, ModelBuildingRequest request, ModelProblemCollector problems ) { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java index 8cdc7fb1f9..48eed40bde 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java @@ -1,30 +1,29 @@ package org.apache.maven.plugin; /* - * 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. + * 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. */ -import org.apache.maven.artifact.repository.RepositoryRequest; +import java.util.List; + import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; /** * @author Jason van Zyl @@ -32,12 +31,13 @@ public interface BuildPluginManager { // igorf: Way too many declared exceptions! - PluginDescriptor loadPlugin( Plugin plugin, RepositoryRequest repositoryRequest ) + PluginDescriptor loadPlugin( Plugin plugin, List repositories, RepositorySystemSession session ) throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException; // igorf: Way too many declared exceptions! - MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryRequest repositoryRequest ) + MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List repositories, + RepositorySystemSession session ) throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException; diff --git a/maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java b/maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java new file mode 100644 index 0000000000..ec8c4af77d --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java @@ -0,0 +1,211 @@ +package org.apache.maven.plugin; + +/* + * 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. + */ + +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.Plugin; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.RepositoryPolicy; +import org.sonatype.aether.repository.WorkspaceReader; +import org.sonatype.aether.repository.WorkspaceRepository; + +/** + * @author Benjamin Bentmann + */ +class CacheUtils +{ + + public static boolean eq( T s1, T s2 ) + { + return s1 != null ? s1.equals( s2 ) : s2 == null; + } + + public static int hash( Object obj ) + { + return obj != null ? obj.hashCode() : 0; + } + + public static int repositoriesHashCode( List repositories ) + { + int result = 17; + for ( RemoteRepository repository : repositories ) + { + result = 31 * result + repositoryHashCode( repository ); + } + return result; + } + + private static int repositoryHashCode( RemoteRepository repository ) + { + int result = 17; + result = 31 * result + hash( repository.getUrl() ); + return result; + } + + private static boolean repositoryEquals( RemoteRepository r1, RemoteRepository r2 ) + { + if ( r1 == r2 ) + { + return true; + } + + return eq( r1.getId(), r2.getId() ) && eq( r1.getUrl(), r2.getUrl() ) + && policyEquals( r1.getPolicy( false ), r2.getPolicy( false ) ) + && policyEquals( r1.getPolicy( true ), r2.getPolicy( true ) ); + } + + private static boolean policyEquals( RepositoryPolicy p1, RepositoryPolicy p2 ) + { + if ( p1 == p2 ) + { + return true; + } + // update policy doesn't affect contents + return p1.isEnabled() == p2.isEnabled() && eq( p1.getChecksumPolicy(), p2.getChecksumPolicy() ); + } + + public static boolean repositoriesEquals( List r1, List r2 ) + { + if ( r1.size() != r2.size() ) + { + return false; + } + + for ( Iterator it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); ) + { + if ( !repositoryEquals( it1.next(), it2.next() ) ) + { + return false; + } + } + + return true; + } + + public static int pluginHashCode( Plugin plugin ) + { + int hash = 17; + + hash = hash * 31 + hash( plugin.getGroupId() ); + hash = hash * 31 + hash( plugin.getArtifactId() ); + hash = hash * 31 + hash( plugin.getVersion() ); + + hash = hash * 31 + ( plugin.isExtensions() ? 1 : 0 ); + + for ( Dependency dependency : plugin.getDependencies() ) + { + hash = hash * 31 + hash( dependency.getGroupId() ); + hash = hash * 31 + hash( dependency.getArtifactId() ); + hash = hash * 31 + hash( dependency.getVersion() ); + hash = hash * 31 + hash( dependency.getType() ); + hash = hash * 31 + hash( dependency.getClassifier() ); + hash = hash * 31 + hash( dependency.getScope() ); + + for ( Exclusion exclusion : dependency.getExclusions() ) + { + hash = hash * 31 + hash( exclusion.getGroupId() ); + hash = hash * 31 + hash( exclusion.getArtifactId() ); + } + } + + return hash; + } + + public static boolean pluginEquals( Plugin a, Plugin b ) + { + return eq( a.getArtifactId(), b.getArtifactId() ) // + && eq( a.getGroupId(), b.getGroupId() ) // + && eq( a.getVersion(), b.getVersion() ) // + && a.isExtensions() == b.isExtensions() // + && dependenciesEquals( a.getDependencies(), b.getDependencies() ); + } + + private static boolean dependenciesEquals( List a, List b ) + { + if ( a.size() != b.size() ) + { + return false; + } + + Iterator aI = a.iterator(); + Iterator bI = b.iterator(); + + while ( aI.hasNext() ) + { + Dependency aD = aI.next(); + Dependency bD = bI.next(); + + boolean r = eq( aD.getGroupId(), bD.getGroupId() ) // + && eq( aD.getArtifactId(), bD.getArtifactId() ) // + && eq( aD.getVersion(), bD.getVersion() ) // + && eq( aD.getType(), bD.getType() ) // + && eq( aD.getClassifier(), bD.getClassifier() ) // + && eq( aD.getScope(), bD.getScope() ); + + r &= exclusionsEquals( aD.getExclusions(), bD.getExclusions() ); + + if ( !r ) + { + return false; + } + } + + return true; + } + + private static boolean exclusionsEquals( List a, List b ) + { + if ( a.size() != b.size() ) + { + return false; + } + + Iterator aI = a.iterator(); + Iterator bI = b.iterator(); + + while ( aI.hasNext() ) + { + Exclusion aD = aI.next(); + Exclusion bD = bI.next(); + + boolean r = eq( aD.getGroupId(), bD.getGroupId() ) // + && eq( aD.getArtifactId(), bD.getArtifactId() ); + + if ( !r ) + { + return false; + } + } + + return true; + } + + public static WorkspaceRepository getWorkspace( RepositorySystemSession session ) + { + WorkspaceReader reader = session.getWorkspaceReader(); + return ( reader != null ) ? reader.getRepository() : null; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java index 4005349b47..3939d75a65 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java @@ -1,28 +1,24 @@ package org.apache.maven.plugin; /* - * 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. + * 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. */ import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.util.List; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.descriptor.MojoDescriptor; @@ -32,11 +28,13 @@ import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; // TODO: the antrun plugin has its own configurator, the only plugin that does. might need to think about how that works // TODO: remove the coreArtifactFilterManager -@Component( role = BuildPluginManager.class ) +@Component(role = BuildPluginManager.class) public class DefaultBuildPluginManager implements BuildPluginManager { @@ -51,19 +49,18 @@ public class DefaultBuildPluginManager private LegacySupport legacySupport; /** - * + * * @param plugin * @param repositoryRequest * @return PluginDescriptor The component descriptor for the Maven plugin. * @throws PluginNotFoundException The plugin could not be found in any repositories. * @throws PluginResolutionException The plugin could be found but could not be resolved. - * @throws InvalidPluginDescriptorException + * @throws InvalidPluginDescriptorException */ - public PluginDescriptor loadPlugin( Plugin plugin, RepositoryRequest repositoryRequest ) - throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, - InvalidPluginDescriptorException + public PluginDescriptor loadPlugin( Plugin plugin, List repositories, RepositorySystemSession session ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { - return mavenPluginManager.getPluginDescriptor( plugin, repositoryRequest ); + return mavenPluginManager.getPluginDescriptor( plugin, repositories, session ); } // ---------------------------------------------------------------------- @@ -175,9 +172,9 @@ public void executeMojo( MavenSession session, MojoExecution mojoExecution ) /** * TODO pluginDescriptor classRealm and artifacts are set as a side effect of this * call, which is not nice. - * @throws PluginResolutionException + * @throws PluginResolutionException */ - public ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor ) + public ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor ) throws PluginResolutionException, PluginManagerException { ClassRealm pluginRealm = pluginDescriptor.getClassRealm(); @@ -192,11 +189,12 @@ public ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginD return pluginDescriptor.getClassRealm(); } - public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryRequest repositoryRequest ) + public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List repositories, + RepositorySystemSession session ) throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException { - return mavenPluginManager.getMojoDescriptor( plugin, goal, repositoryRequest ); + return mavenPluginManager.getMojoDescriptor( plugin, goal, repositories, session ); } } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java index fe3f4db276..6348b738ee 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java @@ -25,11 +25,11 @@ import java.util.List; import java.util.Map; -import org.apache.maven.artifact.Artifact; import org.apache.maven.project.ExtensionDescriptor; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.artifact.Artifact; /** * Default extension realm cache implementation. Assumes cached data does not change. diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java index e5cb270313..b66dc22c9b 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java @@ -22,19 +22,18 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.model.Dependency; -import org.apache.maven.model.Exclusion; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.WorkspaceRepository; /** * @author Igor Fedorenko @@ -46,36 +45,67 @@ public class DefaultPluginArtifactsCache { private static class CacheKey + implements Key { private final Plugin plugin; - private final List repositories = new ArrayList(); + private final WorkspaceRepository workspace; - private final ArtifactFilter extensionArtifactFilter; + private final LocalRepository localRepo; + + private final List repositories; + + private final DependencyFilter filter; private final int hashCode; - public CacheKey( Plugin plugin, RepositoryRequest repositoryRequest, ArtifactFilter extensionArtifactFilter ) + public CacheKey( Plugin plugin, DependencyFilter extensionFilter, List repositories, + RepositorySystemSession session ) { this.plugin = plugin.clone(); - this.repositories.add( repositoryRequest.getLocalRepository() ); - this.repositories.addAll( repositoryRequest.getRemoteRepositories() ); - this.extensionArtifactFilter = extensionArtifactFilter; + workspace = CacheUtils.getWorkspace( session ); + this.localRepo = session.getLocalRepository(); + this.repositories = new ArrayList( repositories.size() ); + for ( RemoteRepository repository : repositories ) + { + if ( repository.isRepositoryManager() ) + { + this.repositories.addAll( repository.getMirroredRepositories() ); + } + else + { + this.repositories.add( repository ); + } + } + this.filter = extensionFilter; int hash = 17; - hash = hash * 31 + pluginHashCode( plugin ); - hash = hash * 31 + repositories.hashCode(); - hash = hash * 31 + ( extensionArtifactFilter != null ? extensionArtifactFilter.hashCode() : 0 ); + hash = hash * 31 + CacheUtils.pluginHashCode( plugin ); + hash = hash * 31 + hash( workspace ); + hash = hash * 31 + hash( localRepo ); + hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories ); + hash = hash * 31 + hash( extensionFilter ); this.hashCode = hash; } + @Override + public String toString() + { + return plugin.getId(); + } + @Override public int hashCode() { return hashCode; } + private static int hash( Object obj ) + { + return obj != null ? obj.hashCode() : 0; + } + @Override public boolean equals( Object o ) { @@ -89,34 +119,43 @@ public boolean equals( Object o ) return false; } - CacheKey other = (CacheKey) o; + CacheKey that = (CacheKey) o; - return pluginEquals( plugin, other.plugin ) && eq( repositories, other.repositories ) - && eq( extensionArtifactFilter, other.extensionArtifactFilter ); + return CacheUtils.pluginEquals( plugin, that.plugin ) && eq( workspace, that.workspace ) + && eq( localRepo, that.localRepo ) && CacheUtils.repositoriesEquals( repositories, that.repositories ) + && eq( filter, that.filter ); + } + + private static boolean eq( T s1, T s2 ) + { + return s1 != null ? s1.equals( s2 ) : s2 == null; } } - protected final Map cache = new HashMap(); + protected final Map cache = new HashMap(); - public CacheRecord get( Plugin plugin, RepositoryRequest repositoryRequest, ArtifactFilter extensionArtifactFilter ) + public Key createKey( Plugin plugin, DependencyFilter extensionFilter, List repositories, + RepositorySystemSession session ) { - return cache.get( new CacheKey( plugin, repositoryRequest, extensionArtifactFilter ) ); + return new CacheKey( plugin, extensionFilter, repositories, session ); } - public CacheRecord put( Plugin plugin, RepositoryRequest repositoryRequest, ArtifactFilter extensionArtifactFilter, - List pluginArtifacts ) + public CacheRecord get( Key key ) + { + return cache.get( key ); + } + + public CacheRecord put( Key key, List pluginArtifacts ) { if ( pluginArtifacts == null ) { throw new NullPointerException(); } - CacheKey key = new CacheKey( plugin, repositoryRequest, extensionArtifactFilter ); - if ( cache.containsKey( key ) ) { - throw new IllegalStateException( "Duplicate artifact resolution result for plugin " + plugin.getId() ); + throw new IllegalStateException( "Duplicate artifact resolution result for plugin " + key ); } CacheRecord record = @@ -134,102 +173,12 @@ public void flush() protected static int pluginHashCode( Plugin plugin ) { - int hash = 17; - - hash = hash * 31 + plugin.getGroupId().hashCode(); - hash = hash * 31 + plugin.getArtifactId().hashCode(); - hash = hash * 31 + plugin.getVersion().hashCode(); - - for ( Dependency dependency : plugin.getDependencies() ) - { - hash = hash * 31 + dependency.getGroupId().hashCode(); - hash = hash * 31 + dependency.getArtifactId().hashCode(); - hash = hash * 31 + dependency.getVersion().hashCode(); - hash = hash * 31 + dependency.getType().hashCode(); - hash = hash * 31 + ( dependency.getClassifier() != null ? dependency.getClassifier().hashCode() : 0 ); - hash = hash * 31 + ( dependency.getScope() != null ? dependency.getScope().hashCode() : 0 ); - - for ( Exclusion exclusion : dependency.getExclusions() ) - { - hash = hash * 31 + exclusion.getGroupId().hashCode(); - hash = hash * 31 + exclusion.getArtifactId().hashCode(); - } - } - - return hash; + return CacheUtils.pluginHashCode( plugin ); } protected static boolean pluginEquals( Plugin a, Plugin b ) { - return eq( a.getGroupId(), b.getGroupId() ) // - && eq( a.getArtifactId(), b.getArtifactId() ) // - && eq( a.getVersion(), b.getVersion() ) // - && dependenciesEquals( a.getDependencies(), b.getDependencies() ); - } - - private static boolean dependenciesEquals( List a, List b ) - { - if ( a.size() != b.size() ) - { - return false; - } - - Iterator aI = a.iterator(); - Iterator bI = b.iterator(); - - while ( aI.hasNext() ) - { - Dependency aD = aI.next(); - Dependency bD = bI.next(); - - boolean r = eq( aD.getGroupId(), bD.getGroupId() ) // - && eq( aD.getArtifactId(), bD.getArtifactId() ) // - && eq( aD.getVersion(), bD.getVersion() ) // - && eq( aD.getType(), bD.getType() ) // - && eq( aD.getClassifier(), bD.getClassifier() ) // - && eq( aD.getScope(), bD.getScope() ); - - r &= exclusionsEquals( aD.getExclusions(), bD.getExclusions() ); - - if ( !r ) - { - return false; - } - } - - return true; - } - - private static boolean exclusionsEquals( List a, List b ) - { - if ( a.size() != b.size() ) - { - return false; - } - - Iterator aI = a.iterator(); - Iterator bI = b.iterator(); - - while ( aI.hasNext() ) - { - Exclusion aD = aI.next(); - Exclusion bD = bI.next(); - - boolean r = eq( aD.getGroupId(), bD.getGroupId() ) // - && eq( aD.getArtifactId(), bD.getArtifactId() ); - - if ( !r ) - { - return false; - } - } - - return true; - } - - private static boolean eq( T s1, T s2 ) - { - return s1 != null ? s1.equals( s2 ) : s2 == null; + return CacheUtils.pluginEquals( a, b ); } public void register( MavenProject project, CacheRecord record ) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java index fa1ae0a182..35f7cbad8f 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java @@ -21,19 +21,19 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.maven.artifact.ArtifactUtils; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.repository.ComponentDescriptor; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.WorkspaceRepository; /** * Caches raw plugin descriptors. A raw plugin descriptor is a descriptor that has just been extracted from the plugin @@ -57,14 +57,9 @@ public void flush() descriptors.clear(); } - public Key createKey( Plugin plugin, RepositoryRequest repositoryRequest ) + public Key createKey( Plugin plugin, List repositories, RepositorySystemSession session ) { - return new CacheKey( plugin, repositoryRequest ); - } - - public void put( Key cacheKey, PluginDescriptor pluginDescriptor ) - { - descriptors.put( cacheKey, clone( pluginDescriptor ) ); + return new CacheKey( plugin, repositories, session ); } public PluginDescriptor get( Key cacheKey ) @@ -72,6 +67,11 @@ public PluginDescriptor get( Key cacheKey ) return clone( descriptors.get( cacheKey ) ); } + public void put( Key cacheKey, PluginDescriptor pluginDescriptor ) + { + descriptors.put( cacheKey, clone( pluginDescriptor ) ); + } + private static PluginDescriptor clone( PluginDescriptor original ) { PluginDescriptor clone = null; @@ -129,25 +129,42 @@ private static final class CacheKey private final String version; - private final List repositories; + private final WorkspaceRepository workspace; + + private final LocalRepository localRepo; + + private final List repositories; private final int hashCode; - public CacheKey( Plugin plugin, RepositoryRequest repositoryRequest ) + public CacheKey( Plugin plugin, List repositories, RepositorySystemSession session ) { groupId = plugin.getGroupId(); artifactId = plugin.getArtifactId(); version = plugin.getVersion(); - repositories = new ArrayList( repositoryRequest.getRemoteRepositories().size() + 1 ); - repositories.add( repositoryRequest.getLocalRepository() ); - repositories.addAll( repositoryRequest.getRemoteRepositories() ); + workspace = CacheUtils.getWorkspace( session ); + localRepo = session.getLocalRepository(); + this.repositories = new ArrayList( repositories.size() ); + for ( RemoteRepository repository : repositories ) + { + if ( repository.isRepositoryManager() ) + { + this.repositories.addAll( repository.getMirroredRepositories() ); + } + else + { + this.repositories.add( repository ); + } + } int hash = 17; hash = hash * 31 + groupId.hashCode(); hash = hash * 31 + artifactId.hashCode(); hash = hash * 31 + version.hashCode(); - hash = hash * 31 + repositoriesHashCode( repositories ); + hash = hash * 31 + hash( workspace ); + hash = hash * 31 + localRepo.hashCode(); + hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories ); this.hashCode = hash; } @@ -172,8 +189,10 @@ public boolean equals( Object obj ) CacheKey that = (CacheKey) obj; - return this.artifactId.equals( that.artifactId ) && this.groupId.equals( that.groupId ) - && this.version.equals( that.version ) && repositoriesEquals( this.repositories, that.repositories ); + return eq( this.artifactId, that.artifactId ) && eq( this.groupId, that.groupId ) + && eq( this.version, that.version ) && eq( this.localRepo, that.localRepo ) + && eq( this.workspace, that.workspace ) + && CacheUtils.repositoriesEquals( this.repositories, that.repositories ); } @Override @@ -182,61 +201,9 @@ public String toString() return groupId + ':' + artifactId + ':' + version; } - private static int repositoryHashCode( ArtifactRepository repository ) + private static int hash( Object obj ) { - int result = 17; - result = 31 * result + ( repository.getId() != null ? repository.getId().hashCode() : 0 ); - return result; - } - - private static int repositoriesHashCode( List repositories ) - { - int result = 17; - for ( ArtifactRepository repository : repositories ) - { - result = 31 * result + repositoryHashCode( repository ); - } - return result; - } - - private static boolean repositoryEquals( ArtifactRepository r1, ArtifactRepository r2 ) - { - if ( r1 == r2 ) - { - return true; - } - - return eq( r1.getId(), r2.getId() ) && eq( r1.getUrl(), r2.getUrl() ) - && repositoryPolicyEquals( r1.getReleases(), r2.getReleases() ) - && repositoryPolicyEquals( r1.getSnapshots(), r2.getSnapshots() ); - } - - private static boolean repositoryPolicyEquals( ArtifactRepositoryPolicy p1, ArtifactRepositoryPolicy p2 ) - { - if ( p1 == p2 ) - { - return true; - } - - return p1.isEnabled() == p2.isEnabled() && eq( p1.getUpdatePolicy(), p2.getUpdatePolicy() ); - } - - private static boolean repositoriesEquals( List r1, List r2 ) - { - if ( r1.size() != r2.size() ) - { - return false; - } - - for ( Iterator it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); ) - { - if ( !repositoryEquals( it1.next(), it2.next() ) ) - { - return false; - } - } - - return true; + return obj != null ? obj.hashCode() : 0; } private static boolean eq( T s1, T s2 ) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java index 2e73beed79..f1b46bb9bf 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java @@ -21,20 +21,20 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.model.Dependency; -import org.apache.maven.model.Exclusion; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.WorkspaceRepository; /** * Default PluginCache implementation. Assumes cached data does not change. @@ -45,45 +45,76 @@ public class DefaultPluginRealmCache { protected static class CacheKey + implements Key { + private final Plugin plugin; - private final List repositories = new ArrayList(); + private final WorkspaceRepository workspace; + + private final LocalRepository localRepo; + + private final List repositories; private final ClassLoader parentRealm; private final List parentImports; - private final ArtifactFilter filter; + private final DependencyFilter filter; private final int hashCode; public CacheKey( Plugin plugin, ClassLoader parentRealm, List parentImports, - ArtifactFilter dependencyFilter, ArtifactRepository localRepository, - List remoteRepositories ) + DependencyFilter dependencyFilter, List repositories, + RepositorySystemSession session ) { this.plugin = plugin.clone(); - this.repositories.add( localRepository ); - this.repositories.addAll( remoteRepositories ); + this.workspace = CacheUtils.getWorkspace( session ); + this.localRepo = session.getLocalRepository(); + this.repositories = new ArrayList( repositories.size() ); + for ( RemoteRepository repository : repositories ) + { + if ( repository.isRepositoryManager() ) + { + this.repositories.addAll( repository.getMirroredRepositories() ); + } + else + { + this.repositories.add( repository ); + } + } this.parentRealm = parentRealm; this.parentImports = ( parentImports != null ) ? parentImports : Collections. emptyList(); this.filter = dependencyFilter; int hash = 17; - hash = hash * 31 + pluginHashCode( plugin ); - hash = hash * 31 + repositories.hashCode(); - hash = hash * 31 + ( parentRealm != null ? parentRealm.hashCode() : 0 ); + hash = hash * 31 + CacheUtils.pluginHashCode( plugin ); + hash = hash * 31 + hash( workspace ); + hash = hash * 31 + hash( localRepo ); + hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories ); + hash = hash * 31 + hash( parentRealm ); hash = hash * 31 + this.parentImports.hashCode(); - hash = hash * 31 + ( dependencyFilter != null ? dependencyFilter.hashCode() : 0 ); + hash = hash * 31 + hash( dependencyFilter ); this.hashCode = hash; } + @Override + public String toString() + { + return plugin.getId(); + } + @Override public int hashCode() { return hashCode; } + private static int hash( Object obj ) + { + return obj != null ? obj.hashCode() : 0; + } + @Override public boolean equals( Object o ) { @@ -97,40 +128,45 @@ public boolean equals( Object o ) return false; } - CacheKey other = (CacheKey) o; + CacheKey that = (CacheKey) o; - return parentRealm == other.parentRealm && pluginEquals( plugin, other.plugin ) - && eq( repositories, other.repositories ) && eq( filter, other.filter ) - && eq( parentImports, other.parentImports ); + return parentRealm == that.parentRealm && CacheUtils.pluginEquals( plugin, that.plugin ) + && eq( workspace, that.workspace ) && eq( localRepo, that.localRepo ) + && CacheUtils.repositoriesEquals( this.repositories, that.repositories ) && eq( filter, that.filter ) + && eq( parentImports, that.parentImports ); } + + private static boolean eq( T s1, T s2 ) + { + return s1 != null ? s1.equals( s2 ) : s2 == null; + } + } - protected final Map cache = new ConcurrentHashMap(); + protected final Map cache = new ConcurrentHashMap(); - public CacheRecord get( Plugin plugin, ClassLoader parentRealm, List parentImports, - ArtifactFilter dependencyFilter, ArtifactRepository localRepository, - List remoteRepositories ) + public Key createKey( Plugin plugin, ClassLoader parentRealm, List parentImports, + DependencyFilter dependencyFilter, List repositories, + RepositorySystemSession session ) { - return cache.get( new CacheKey( plugin, parentRealm, parentImports, dependencyFilter, localRepository, - remoteRepositories ) ); + return new CacheKey( plugin, parentRealm, parentImports, dependencyFilter, repositories, session ); } - public CacheRecord put( Plugin plugin, ClassLoader parentRealm, List parentImports, - ArtifactFilter dependencyFilter, ArtifactRepository localRepository, - List remoteRepositories, ClassRealm pluginRealm, - List pluginArtifacts ) + public CacheRecord get( Key key ) + { + return cache.get( key ); + } + + public CacheRecord put( Key key, ClassRealm pluginRealm, List pluginArtifacts ) { if ( pluginRealm == null || pluginArtifacts == null ) { - throw new NullPointerException(); + throw new IllegalArgumentException(); } - CacheKey key = - new CacheKey( plugin, parentRealm, parentImports, dependencyFilter, localRepository, remoteRepositories ); - if ( cache.containsKey( key ) ) { - throw new IllegalStateException( "Duplicate plugin realm for plugin " + plugin.getId() ); + throw new IllegalStateException( "Duplicate plugin realm for plugin " + key ); } CacheRecord record = new CacheRecord( pluginRealm, pluginArtifacts ); @@ -147,105 +183,12 @@ public void flush() protected static int pluginHashCode( Plugin plugin ) { - int hash = 17; - - hash = hash * 31 + plugin.getGroupId().hashCode(); - hash = hash * 31 + plugin.getArtifactId().hashCode(); - hash = hash * 31 + plugin.getVersion().hashCode(); - - hash = hash * 31 + ( plugin.isExtensions() ? 1 : 0 ); - - for ( Dependency dependency : plugin.getDependencies() ) - { - hash = hash * 31 + dependency.getGroupId().hashCode(); - hash = hash * 31 + dependency.getArtifactId().hashCode(); - hash = hash * 31 + dependency.getVersion().hashCode(); - hash = hash * 31 + dependency.getType().hashCode(); - hash = hash * 31 + ( dependency.getClassifier() != null ? dependency.getClassifier().hashCode() : 0 ); - hash = hash * 31 + ( dependency.getScope() != null ? dependency.getScope().hashCode() : 0 ); - - for ( Exclusion exclusion : dependency.getExclusions() ) - { - hash = hash * 31 + exclusion.getGroupId().hashCode(); - hash = hash * 31 + exclusion.getArtifactId().hashCode(); - } - } - - return hash; + return CacheUtils.pluginHashCode( plugin ); } protected static boolean pluginEquals( Plugin a, Plugin b ) { - return eq( a.getGroupId(), b.getGroupId() ) // - && eq( a.getArtifactId(), b.getArtifactId() ) // - && eq( a.getVersion(), b.getVersion() ) // - && a.isExtensions() == b.isExtensions() // - && dependenciesEquals( a.getDependencies(), b.getDependencies() ); - } - - private static boolean dependenciesEquals( List a, List b ) - { - if ( a.size() != b.size() ) - { - return false; - } - - Iterator aI = a.iterator(); - Iterator bI = b.iterator(); - - while ( aI.hasNext() ) - { - Dependency aD = aI.next(); - Dependency bD = bI.next(); - - boolean r = eq( aD.getGroupId(), bD.getGroupId() ) // - && eq( aD.getArtifactId(), bD.getArtifactId() ) // - && eq( aD.getVersion(), bD.getVersion() ) // - && eq( aD.getType(), bD.getType() ) // - && eq( aD.getClassifier(), bD.getClassifier() ) // - && eq( aD.getScope(), bD.getScope() ); - - r &= exclusionsEquals( aD.getExclusions(), bD.getExclusions() ); - - if ( !r ) - { - return false; - } - } - - return true; - } - - private static boolean exclusionsEquals( List a, List b ) - { - if ( a.size() != b.size() ) - { - return false; - } - - Iterator aI = a.iterator(); - Iterator bI = b.iterator(); - - while ( aI.hasNext() ) - { - Exclusion aD = aI.next(); - Exclusion bD = bI.next(); - - boolean r = eq( aD.getGroupId(), bD.getGroupId() ) // - && eq( aD.getArtifactId(), bD.getArtifactId() ); - - if ( !r ) - { - return false; - } - } - - return true; - } - - private static boolean eq( T s1, T s2 ) - { - return s1 != null ? s1.equals( s2 ) : s2 == null; + return CacheUtils.pluginEquals( a, b ); } public void register( MavenProject project, CacheRecord record ) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java index 8124798688..6a0da57cf6 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java @@ -21,10 +21,10 @@ import java.util.List; -import org.apache.maven.artifact.Artifact; import org.apache.maven.project.ExtensionDescriptor; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.sonatype.aether.artifact.Artifact; /** * Caches extension class realms. Warning: This is an internal utility interface that is only public diff --git a/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java b/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java index 0e3c66dd0f..30f4d0f2eb 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java @@ -24,12 +24,10 @@ public class InvalidPluginDescriptorException extends Exception { - private List errors; public InvalidPluginDescriptorException( String message, List errors ) { super( toMessage( message, errors ) ); - this.errors = errors; } private static String toMessage( String message, List errors ) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java b/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java index c6b9f947ae..02eea95ffa 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java @@ -20,6 +20,7 @@ */ import org.apache.maven.execution.MavenSession; +import org.sonatype.aether.RepositorySystemSession; /** * Helps to provide backward-compatibility with plugins that use legacy components. Warning: This is an @@ -48,4 +49,11 @@ public interface LegacySupport */ MavenSession getSession(); + /** + * Gets the currently active repository session. + * + * @return The currently active repository session or {@code null} if none. + */ + RepositorySystemSession getRepositorySession(); + } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java index e488af9f77..f496cd4ec3 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java @@ -21,12 +21,13 @@ import java.util.List; -import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.repository.RemoteRepository; /** * Provides basic services to manage Maven plugins and their mojos. This component is kept general in its design such @@ -43,11 +44,12 @@ public interface MavenPluginManager * Retrieves the descriptor for the specified plugin from its main artifact. * * @param plugin The plugin whose descriptor should be retrieved, must not be {@code null}. - * @param repositoryRequest The repository request to use for resolving the plugin's main artifact, must not be - * {@code null}. + * @param repositories The plugin repositories to use for resolving the plugin's main artifact, must not be {@code + * null}. + * @param session The repository session to use for resolving the plugin's main artifact, must not be {@code null}. * @return The plugin descriptor, never {@code null}. */ - PluginDescriptor getPluginDescriptor( Plugin plugin, RepositoryRequest repositoryRequest ) + PluginDescriptor getPluginDescriptor( Plugin plugin, List repositories, RepositorySystemSession session ) throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException; /** @@ -55,11 +57,13 @@ PluginDescriptor getPluginDescriptor( Plugin plugin, RepositoryRequest repositor * * @param plugin The plugin whose mojo descriptor should be retrieved, must not be {@code null}. * @param goal The simple name of the mojo whose descriptor should be retrieved, must not be {@code null}. - * @param repositoryRequest The repository request to use for resolving the plugin's main artifact, must not be - * {@code null}. + * @param repositories The plugin repositories to use for resolving the plugin's main artifact, must not be {@code + * null}. + * @param session The repository session to use for resolving the plugin's main artifact, must not be {@code null}. * @return The mojo descriptor, never {@code null}. */ - MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryRequest repositoryRequest ) + MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List repositories, + RepositorySystemSession session ) throws MojoNotFoundException, PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException; @@ -76,7 +80,7 @@ MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryRequest * @param filter The filter used to exclude certain plugin dependencies, may be {@code null}. */ void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session, ClassLoader parent, - List imports, ArtifactFilter filter ) + List imports, DependencyFilter filter ) throws PluginResolutionException, PluginContainerException; /** diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java index d34083a2d5..7114b8f7ae 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java @@ -21,11 +21,12 @@ import java.util.List; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.repository.RemoteRepository; /** * Caches plugin artifacts. Warning: This is an internal utility interface that is only public for @@ -38,6 +39,14 @@ public interface PluginArtifactsCache { + /** + * A cache key. + */ + interface Key + { + // marker interface for cache keys + } + public static class CacheRecord { @@ -50,10 +59,12 @@ public CacheRecord( List artifacts ) } - CacheRecord get( Plugin plugin, RepositoryRequest repositoryRequest, ArtifactFilter extensionArtifactFilter ); + Key createKey( Plugin plugin, DependencyFilter extensionFilter, List repositories, + RepositorySystemSession session ); - CacheRecord put( Plugin plugin, RepositoryRequest repositoryRequest, ArtifactFilter extensionArtifactFilter, - List pluginArtifacts ); + CacheRecord get( Key key ); + + CacheRecord put( Key key, List pluginArtifacts ); void flush(); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java index 1f40720859..6f6ac06871 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java @@ -19,9 +19,12 @@ * under the License. */ -import org.apache.maven.artifact.repository.RepositoryRequest; +import java.util.List; + import org.apache.maven.model.Plugin; import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; /** * Caches raw plugin descriptors. A raw plugin descriptor is a descriptor that has just been extracted from the plugin @@ -44,11 +47,11 @@ interface Key // marker interface for cache keys } - Key createKey( Plugin plugin, RepositoryRequest repositoryRequest ); + Key createKey( Plugin plugin, List repositories, RepositorySystemSession session ); - void put( Key cacheKey, PluginDescriptor pluginDescriptor ); + void put( Key key, PluginDescriptor pluginDescriptor ); - PluginDescriptor get( Key cacheKey ); + PluginDescriptor get( Key key ); void flush(); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java index f559bdad75..7d57b36346 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java @@ -28,12 +28,9 @@ public class PluginDescriptorParsingException extends Exception { - private Plugin plugin; - public PluginDescriptorParsingException( Plugin plugin, String descriptorLocation, Throwable e ) { super( createMessage( plugin, descriptorLocation, e ), e ); - this.plugin = plugin; } private static String createMessage( Plugin plugin, String descriptorLocation, Throwable e ) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java index bd1cc34242..017c8c7c81 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java @@ -229,6 +229,10 @@ else if ( expression.startsWith( "project" ) || expression.startsWith( "pom" ) ) e ); } } + else if ( expression.equals( "repositorySystemSession" ) ) + { + value = session.getRepositorySession(); + } else if ( expression.equals( "mojo" ) ) { value = mojoExecution; diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java index 56deb5f6de..faf89029c0 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java @@ -22,17 +22,18 @@ import java.util.List; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.repository.RemoteRepository; /** * Caches plugin class realms. Warning: This is an internal utility interface that is only public for * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without * prior notice. - * + * * @author Igor Fedorenko * @author Benjamin Bentmann */ @@ -42,6 +43,7 @@ public interface PluginRealmCache public static class CacheRecord { public final ClassRealm realm; + public final List artifacts; public CacheRecord( ClassRealm realm, List artifacts ) @@ -51,14 +53,20 @@ public CacheRecord( ClassRealm realm, List artifacts ) } } - CacheRecord get( Plugin plugin, ClassLoader parentRealm, List parentImports, - ArtifactFilter dependencyFilter, ArtifactRepository localRepository, - List remoteRepositories ); + /** + * A cache key. + */ + interface Key + { + // marker interface for cache keys + } - CacheRecord put( Plugin plugin, ClassLoader parentRealm, List parentImports, - ArtifactFilter dependencyFilter, ArtifactRepository localRepository, - List remoteRepositories, ClassRealm pluginRealm, - List pluginArtifacts ); + Key createKey( Plugin plugin, ClassLoader parentRealm, List parentImports, + DependencyFilter dependencyFilter, List repositories, RepositorySystemSession session ); + + CacheRecord get( Key key ); + + CacheRecord put( Key key, ClassRealm pluginRealm, List pluginArtifacts ); void flush(); @@ -66,7 +74,7 @@ CacheRecord put( Plugin plugin, ClassLoader parentRealm, List parentImpo * Registers the specified cache record for usage with the given project. Integrators can use the information * collected from this method in combination with a custom cache implementation to dispose unused records from the * cache. - * + * * @param project The project that employs the plugin realm, must not be {@code null}. * @param record The cache record being used for the project, must not be {@code null}. */ diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java index b5e10da728..5c381d956c 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java @@ -19,8 +19,6 @@ * under the License. */ -import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.model.Plugin; /** @@ -30,15 +28,15 @@ * @version $Id$ */ public class PluginResolutionException - extends AbstractArtifactResolutionException + extends Exception { + private final Plugin plugin; - public PluginResolutionException( Plugin plugin, ArtifactResolutionException e ) + public PluginResolutionException( Plugin plugin, Throwable cause ) { - super( "Plugin " + plugin.getId() + " or one of its dependencies could not be resolved: " + e.getMessage(), - e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getType(), null, e.getRemoteRepositories(), null, - e ); + super( "Plugin " + plugin.getId() + " or one of its dependencies could not be resolved: " + cause.getMessage(), + cause ); this.plugin = plugin; } @@ -46,4 +44,5 @@ public Plugin getPlugin() { return plugin; } + } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java index 970fd39ba8..78ee4c66da 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java @@ -22,6 +22,7 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.RepositorySystemSession; /** * Helps to provide backward-compatibility with plugins that use legacy components. Warning: This is an @@ -55,4 +56,10 @@ public MavenSession getSession() return session.get(); } + public RepositorySystemSession getRepositorySession() + { + MavenSession session = getSession(); + return ( session != null ) ? session.getRepositorySession() : null; + } + } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java index d46ad3d01f..904ea00503 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -28,18 +28,16 @@ import java.io.PrintStream; import java.io.Reader; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.jar.JarFile; import java.util.zip.ZipEntry; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.filter.AndArtifactFilter; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.classrealm.ClassRealmManager; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; @@ -86,6 +84,12 @@ import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.util.filter.AndDependencyFilter; +import org.sonatype.aether.util.graph.PreorderNodeListGenerator; /** * Provides basic services to manage Maven plugins and their mojos. This component is kept general in its design such @@ -120,17 +124,17 @@ public class DefaultMavenPluginManager private PluginDescriptorBuilder builder = new PluginDescriptorBuilder(); - public synchronized PluginDescriptor getPluginDescriptor( Plugin plugin, RepositoryRequest repositoryRequest ) + public synchronized PluginDescriptor getPluginDescriptor( Plugin plugin, List repositories, RepositorySystemSession session ) throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { - PluginDescriptorCache.Key cacheKey = pluginDescriptorCache.createKey( plugin, repositoryRequest ); + PluginDescriptorCache.Key cacheKey = pluginDescriptorCache.createKey( plugin, repositories, session ); PluginDescriptor pluginDescriptor = pluginDescriptorCache.get( cacheKey ); if ( pluginDescriptor == null ) { Artifact pluginArtifact = - pluginDependenciesResolver.resolve( plugin, new ArtifactResolutionRequest( repositoryRequest ) ); + RepositoryUtils.toArtifact( pluginDependenciesResolver.resolve( plugin, repositories, session ) ); pluginDescriptor = extractPluginDescriptor( pluginArtifact, plugin ); @@ -239,11 +243,12 @@ private PluginDescriptor parsePluginDescriptor( InputStream is, Plugin plugin, S } } - public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryRequest repositoryRequest ) + public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List repositories, + RepositorySystemSession session ) throws MojoNotFoundException, PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { - PluginDescriptor pluginDescriptor = getPluginDescriptor( plugin, repositoryRequest ); + PluginDescriptor pluginDescriptor = getPluginDescriptor( plugin, repositories, session ); MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal ); @@ -256,16 +261,18 @@ public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryR } public synchronized void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session, - ClassLoader parent, List imports, ArtifactFilter filter ) + ClassLoader parent, List imports, DependencyFilter filter ) throws PluginResolutionException, PluginContainerException { Plugin plugin = pluginDescriptor.getPlugin(); MavenProject project = session.getCurrentProject(); - PluginRealmCache.CacheRecord cacheRecord = - pluginRealmCache.get( plugin, parent, imports, filter, session.getLocalRepository(), - project.getPluginArtifactRepositories() ); + PluginRealmCache.Key cacheKey = + pluginRealmCache.createKey( plugin, parent, imports, filter, project.getRemotePluginRepositories(), + session.getRepositorySession() ); + + PluginRealmCache.CacheRecord cacheRecord = pluginRealmCache.get( cacheKey ); if ( cacheRecord != null ) { @@ -277,16 +284,14 @@ public synchronized void setupPluginRealm( PluginDescriptor pluginDescriptor, Ma createPluginRealm( pluginDescriptor, session, parent, imports, filter ); cacheRecord = - pluginRealmCache.put( plugin, parent, imports, filter, session.getLocalRepository(), - project.getPluginArtifactRepositories(), pluginDescriptor.getClassRealm(), - pluginDescriptor.getArtifacts() ); + pluginRealmCache.put( cacheKey, pluginDescriptor.getClassRealm(), pluginDescriptor.getArtifacts() ); } pluginRealmCache.register( project, cacheRecord ); } private void createPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session, ClassLoader parent, - List imports, ArtifactFilter filter ) + List imports, DependencyFilter filter ) throws PluginResolutionException, PluginContainerException { Plugin plugin = pluginDescriptor.getPlugin(); @@ -305,42 +310,32 @@ private void createPluginRealm( PluginDescriptor pluginDescriptor, MavenSession MavenProject project = session.getCurrentProject(); - ArtifactResolutionRequest request = new ArtifactResolutionRequest(); - request.setLocalRepository( session.getLocalRepository() ); - request.setRemoteRepositories( project.getPluginArtifactRepositories() ); - request.setCache( session.getRepositoryCache() ); - request.setOffline( session.isOffline() ); - request.setForceUpdate( session.getRequest().isUpdateSnapshots() ); - request.setServers( session.getRequest().getServers() ); - request.setMirrors( session.getRequest().getMirrors() ); - request.setProxies( session.getRequest().getProxies() ); - request.setTransferListener( session.getRequest().getTransferListener() ); + DependencyFilter dependencyFilter = project.getExtensionDependencyFilter(); + dependencyFilter = AndDependencyFilter.newInstance( dependencyFilter, filter ); - ArtifactFilter dependencyFilter = project.getExtensionArtifactFilter(); - if ( dependencyFilter == null ) + DependencyNode root = + pluginDependenciesResolver.resolve( plugin, RepositoryUtils.toArtifact( pluginArtifact ), dependencyFilter, + project.getRemotePluginRepositories(), session.getRepositorySession() ); + + PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); + root.accept( nlg ); + + List exposedPluginArtifacts = new ArrayList( nlg.getNodes().size() ); + RepositoryUtils.toArtifacts( exposedPluginArtifacts, Collections.singleton( root ), + Collections. emptyList(), null ); + for ( Iterator it = exposedPluginArtifacts.iterator(); it.hasNext(); ) { - dependencyFilter = filter; - } - else if ( filter != null ) - { - dependencyFilter = new AndArtifactFilter( Arrays.asList( dependencyFilter, filter ) ); - } - - List pluginArtifacts = - pluginDependenciesResolver.resolve( plugin, pluginArtifact, request, dependencyFilter ); - - ClassRealm pluginRealm = classRealmManager.createPluginRealm( plugin, parent, imports, pluginArtifacts ); - - List exposedPluginArtifacts = new ArrayList(); - - for ( Artifact artifact : pluginArtifacts ) - { - if ( artifact.getFile() != null ) + Artifact artifact = it.next(); + if ( artifact.getFile() == null ) { - exposedPluginArtifacts.add( artifact ); + it.remove(); } } + List pluginArtifacts = nlg.getArtifacts( true ); + + ClassRealm pluginRealm = classRealmManager.createPluginRealm( plugin, parent, imports, pluginArtifacts ); + pluginDescriptor.setClassRealm( pluginRealm ); pluginDescriptor.setArtifacts( exposedPluginArtifacts ); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java index 0aaf1ad616..264d153aee 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java @@ -19,28 +19,37 @@ * under the License. */ -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; import org.apache.maven.ArtifactFilterManager; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; -import org.apache.maven.artifact.resolver.ResolutionErrorHandler; -import org.apache.maven.artifact.resolver.filter.AndArtifactFilter; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; +import org.apache.maven.RepositoryUtils; import org.apache.maven.model.Dependency; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.PluginResolutionException; -import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.logging.Logger; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.collection.CollectRequest; +import org.sonatype.aether.collection.DependencyCollectionException; +import org.sonatype.aether.collection.DependencyGraphTransformer; +import org.sonatype.aether.collection.DependencySelector; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.graph.DependencyVisitor; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.ArtifactResolutionException; +import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.sonatype.aether.util.artifact.DefaultArtifact; +import org.sonatype.aether.util.artifact.JavaScopes; +import org.sonatype.aether.util.filter.AndDependencyFilter; +import org.sonatype.aether.util.filter.ExclusionsDependencyFilter; +import org.sonatype.aether.util.filter.ScopeDependencyFilter; +import org.sonatype.aether.util.graph.selector.AndDependencySelector; +import org.sonatype.aether.util.graph.transformer.ChainedDependencyGraphTransformer; /** * Assists in resolving the dependencies of a plugin. Warning: This is an internal utility class that @@ -55,29 +64,32 @@ public class DefaultPluginDependenciesResolver implements PluginDependenciesResolver { - @Requirement - protected RepositorySystem repositorySystem; + private static final String REPOSITORY_CONTEXT = "plugin"; @Requirement - private ResolutionErrorHandler resolutionErrorHandler; + private Logger logger; @Requirement private ArtifactFilterManager artifactFilterManager; - public Artifact resolve( Plugin plugin, ArtifactResolutionRequest request ) + @Requirement + private RepositorySystem repoSystem; + + private Artifact toArtifact( Plugin plugin, RepositorySystemSession session ) + { + return new DefaultArtifact( plugin.getGroupId(), plugin.getArtifactId(), null, "jar", plugin.getVersion(), + session.getArtifactTypeRegistry().get( "maven-plugin" ) ); + } + + public Artifact resolve( Plugin plugin, List repositories, RepositorySystemSession session ) throws PluginResolutionException { - Artifact pluginArtifact = repositorySystem.createPluginArtifact( plugin ); - - request.setArtifact( pluginArtifact ); - request.setResolveRoot( true ); - request.setResolveTransitively( false ); - - ArtifactResolutionResult result = repositorySystem.resolve( request ); + Artifact pluginArtifact = toArtifact( plugin, session ); try { - resolutionErrorHandler.throwErrors( request, result ); + ArtifactRequest request = new ArtifactRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT ); + pluginArtifact = repoSystem.resolveArtifact( session, request ).getArtifact(); } catch ( ArtifactResolutionException e ) { @@ -87,96 +99,113 @@ public Artifact resolve( Plugin plugin, ArtifactResolutionRequest request ) return pluginArtifact; } - public List resolve( Plugin plugin, Artifact pluginArtifact, ArtifactResolutionRequest request, - ArtifactFilter dependencyFilter ) + public DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter, + List repositories, RepositorySystemSession session ) throws PluginResolutionException { if ( pluginArtifact == null ) { - pluginArtifact = repositorySystem.createPluginArtifact( plugin ); + pluginArtifact = toArtifact( plugin, session ); } - Set overrideArtifacts = new LinkedHashSet(); - for ( Dependency dependency : plugin.getDependencies() ) - { - if ( !Artifact.SCOPE_SYSTEM.equals( dependency.getScope() ) ) - { - dependency.setScope( Artifact.SCOPE_RUNTIME ); - } - overrideArtifacts.add( repositorySystem.createDependencyArtifact( dependency ) ); - } + DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" ); - ArtifactFilter collectionFilter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM ); + DependencyFilter resolutionFilter = + new ExclusionsDependencyFilter( artifactFilterManager.getCoreArtifactExcludes() ); + resolutionFilter = AndDependencyFilter.newInstance( resolutionFilter, dependencyFilter ); + resolutionFilter = new AndDependencyFilter( collectionFilter, resolutionFilter ); - ArtifactFilter resolutionFilter = artifactFilterManager.getCoreArtifactFilter(); - - PluginDependencyResolutionListener listener = new PluginDependencyResolutionListener( resolutionFilter ); - - if ( dependencyFilter != null ) - { - resolutionFilter = new AndArtifactFilter( Arrays.asList( resolutionFilter, dependencyFilter ) ); - } - - request.setArtifact( pluginArtifact ); - request.setArtifactDependencies( overrideArtifacts ); - request.setCollectionFilter( collectionFilter ); - request.setResolutionFilter( resolutionFilter ); - request.setResolveRoot( true ); - request.setResolveTransitively( true ); - request.addListener( listener ); - - ArtifactResolutionResult result = repositorySystem.resolve( request ); + DependencyNode node; try { - resolutionErrorHandler.throwErrors( request, result ); + DependencySelector selector = + AndDependencySelector.newInstance( session.getDependencySelector(), new WagonExcluder() ); + + DependencyGraphTransformer transformer = + ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(), + new PlexusUtilsInjector() ); + + DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session ); + pluginSession.setDependencySelector( selector ); + pluginSession.setDependencyGraphTransformer( transformer ); + + CollectRequest request = new CollectRequest(); + request.setRequestContext( REPOSITORY_CONTEXT ); + request.setRepositories( repositories ); + request.setRoot( new org.sonatype.aether.graph.Dependency( pluginArtifact, null ) ); + for ( Dependency dependency : plugin.getDependencies() ) + { + org.sonatype.aether.graph.Dependency pluginDep = + RepositoryUtils.toDependency( dependency, session.getArtifactTypeRegistry() ); + if ( !JavaScopes.SYSTEM.equals( pluginDep.getScope() ) ) + { + pluginDep = pluginDep.setScope( JavaScopes.RUNTIME ); + } + request.addDependency( pluginDep ); + } + + node = repoSystem.collectDependencies( pluginSession, request ).getRoot(); + + if ( logger.isDebugEnabled() ) + { + node.accept( new GraphLogger() ); + } + + repoSystem.resolveDependencies( session, node, resolutionFilter ); + } + catch ( DependencyCollectionException e ) + { + throw new PluginResolutionException( plugin, e ); } catch ( ArtifactResolutionException e ) { throw new PluginResolutionException( plugin, e ); } - List pluginArtifacts = new ArrayList( result.getArtifacts() ); - - listener.removeBannedDependencies( pluginArtifacts ); - - addPlexusUtils( pluginArtifacts, plugin, request ); - - return pluginArtifacts; + return node; } - // backward-compatibility with Maven 2.x - private void addPlexusUtils( List pluginArtifacts, Plugin plugin, RepositoryRequest repositoryRequest ) - throws PluginResolutionException + class GraphLogger + implements DependencyVisitor { - for ( Artifact artifact : pluginArtifacts ) + + private String indent = ""; + + public boolean visitEnter( DependencyNode node ) { - if ( "org.codehaus.plexus:plexus-utils:jar".equals( artifact.getDependencyConflictId() ) ) + StringBuilder buffer = new StringBuilder( 128 ); + buffer.append( indent ); + org.sonatype.aether.graph.Dependency dep = node.getDependency(); + if ( dep != null ) { - return; + org.sonatype.aether.artifact.Artifact art = dep.getArtifact(); + + buffer.append( art ); + buffer.append( ':' ).append( dep.getScope() ); + + if ( node.getPremanagedScope() != null && !node.getPremanagedScope().equals( dep.getScope() ) ) + { + buffer.append( " (scope managed from " ).append( node.getPremanagedScope() ).append( ")" ); + } + + if ( node.getPremanagedVersion() != null && !node.getPremanagedVersion().equals( art.getVersion() ) ) + { + buffer.append( " (version managed from " ).append( node.getPremanagedVersion() ).append( ")" ); + } } + + logger.debug( buffer.toString() ); + indent += " "; + return true; } - Artifact plexusUtils = - repositorySystem.createArtifact( "org.codehaus.plexus", "plexus-utils", "1.1", Artifact.SCOPE_RUNTIME, - "jar" ); - - ArtifactResolutionRequest request = new ArtifactResolutionRequest( repositoryRequest ); - request.setArtifact( plexusUtils ); - request.setResolveRoot( true ); - request.setResolveTransitively( false ); - - ArtifactResolutionResult result = repositorySystem.resolve( request ); - try + public boolean visitLeave( DependencyNode node ) { - resolutionErrorHandler.throwErrors( request, result ); - } - catch ( ArtifactResolutionException e ) - { - throw new PluginResolutionException( plugin, e ); + indent = indent.substring( 0, indent.length() - 3 ); + return true; } - pluginArtifacts.add( plexusUtils ); } } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java index 168b4ba3f2..5d467e8988 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java @@ -22,8 +22,6 @@ import java.util.Map; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.DefaultRepositoryRequest; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; @@ -100,10 +98,9 @@ public Object getPluginComponent( Plugin plugin, String role, String roleHint ) PluginDescriptor pluginDescriptor; try { - RepositoryRequest repositoryRequest = - DefaultRepositoryRequest.getRepositoryRequest( session, session.getCurrentProject() ); - - pluginDescriptor = pluginManager.getPluginDescriptor( plugin, repositoryRequest ); + pluginDescriptor = + pluginManager.getPluginDescriptor( plugin, session.getCurrentProject().getRemotePluginRepositories(), + session.getRepositorySession() ); pluginManager.setupPluginRealm( pluginDescriptor, session, null, null, null ); } @@ -133,10 +130,9 @@ public Map getPluginComponents( Plugin plugin, String role ) PluginDescriptor pluginDescriptor; try { - RepositoryRequest repositoryRequest = - DefaultRepositoryRequest.getRepositoryRequest( session, session.getCurrentProject() ); - - pluginDescriptor = pluginManager.getPluginDescriptor( plugin, repositoryRequest ); + pluginDescriptor = + pluginManager.getPluginDescriptor( plugin, session.getCurrentProject().getRemotePluginRepositories(), + session.getRepositorySession() ); pluginManager.setupPluginRealm( pluginDescriptor, session, null, null, null ); } @@ -234,24 +230,24 @@ public PluginDescriptor verifyPlugin( Plugin plugin, MavenProject project, Setti InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException, PluginVersionNotFoundException { - RepositoryRequest repositoryRequest = new DefaultRepositoryRequest(); - repositoryRequest.setLocalRepository( localRepository ); - repositoryRequest.setRemoteRepositories( project.getPluginArtifactRepositories() ); - repositoryRequest.setOffline( settings.isOffline() ); + MavenSession session = legacySupport.getSession(); if ( plugin.getVersion() == null ) { - PluginVersionRequest versionRequest = new DefaultPluginVersionRequest( plugin, repositoryRequest ); + PluginVersionRequest versionRequest = + new DefaultPluginVersionRequest( plugin, session.getRepositorySession(), + project.getRemotePluginRepositories() ); plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() ); } try { - return pluginManager.getPluginDescriptor( plugin, repositoryRequest ); + return pluginManager.getPluginDescriptor( plugin, project.getRemotePluginRepositories(), + session.getRepositorySession() ); } catch ( PluginResolutionException e ) { - throw new PluginNotFoundException( plugin, repositoryRequest.getRemoteRepositories() ); + throw new PluginNotFoundException( plugin, project.getPluginArtifactRepositories() ); } catch ( PluginDescriptorParsingException e ) { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java new file mode 100644 index 0000000000..d191a234ac --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java @@ -0,0 +1,87 @@ +package org.apache.maven.plugin.internal; + +/* + * 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. + */ + +import org.sonatype.aether.RepositoryException; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.collection.DependencyGraphTransformationContext; +import org.sonatype.aether.collection.DependencyGraphTransformer; +import org.sonatype.aether.graph.Dependency; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.util.artifact.DefaultArtifact; +import org.sonatype.aether.util.artifact.JavaScopes; +import org.sonatype.aether.util.graph.DefaultDependencyNode; + +/** + * Injects plexus-utils:1.1 into a plugin's class path if it doesn't already declare a dependency on plexus-utils. This + * is another legacy bit to provide backward-compat with Maven 2.x. + * + * @author Benjamin Bentmann + */ +class PlexusUtilsInjector + implements DependencyGraphTransformer +{ + + private static final String GID = "org.codehaus.plexus"; + + private static final String AID = "plexus-utils"; + + private static final String VER = "1.1"; + + private static final String EXT = "jar"; + + public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context ) + throws RepositoryException + { + if ( findPlexusUtils( node ) == null ) + { + Artifact pu = new DefaultArtifact( GID, AID, null, EXT, VER ); + DefaultDependencyNode child = new DefaultDependencyNode( new Dependency( pu, JavaScopes.RUNTIME ) ); + child.setRepositories( node.getRepositories() ); + child.setRequestContext( node.getRequestContext() ); + node.getChildren().add( child ); + } + + return node; + } + + private DependencyNode findPlexusUtils( DependencyNode node ) + { + Artifact artifact = node.getDependency().getArtifact(); + + if ( AID.equals( artifact.getArtifactId() ) && GID.equals( artifact.getGroupId() ) + && EXT.equals( artifact.getExtension() ) && "".equals( artifact.getClassifier() ) ) + { + return node; + } + + for ( DependencyNode child : node.getChildren() ) + { + DependencyNode result = findPlexusUtils( child ); + if ( result != null ) + { + return result; + } + } + + return null; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java index 78cbc481d9..8b33612409 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java @@ -21,11 +21,13 @@ import java.util.List; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.PluginResolutionException; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.repository.RemoteRepository; /** * Assists in resolving the dependencies of a plugin. Warning: This is an internal utility interface @@ -40,29 +42,30 @@ public interface PluginDependenciesResolver /** * Resolves the main artifact of the specified plugin. - * + * * @param plugin The plugin for which to resolve the main artifact, must not be {@code null}. - * @param request A prepopulated resolution request that will be completed and used for the resolution, must not be - * {@code null}. + * @param repositories The plugin repositories to use for resolving the plugin's main artifact, must not be {@code + * null}. + * @param session The repository session to use for resolving the plugin's main artifact, must not be {@code null}. * @return The resolved plugin artifact, never {@code null}. * @throws PluginResolutionException If the plugin artifact could not be resolved. */ - Artifact resolve( Plugin plugin, ArtifactResolutionRequest request ) + public Artifact resolve( Plugin plugin, List repositories, RepositorySystemSession session ) throws PluginResolutionException; /** * Resolves the runtime dependencies of the specified plugin. - * + * * @param plugin The plugin for which to resolve the dependencies, must not be {@code null}. * @param pluginArtifact The plugin's main artifact, may be {@code null}. - * @param request A prepopulated resolution request that will be completed and used for the resolution, must not be - * {@code null}. - * @param dependencyFilter A filter to exclude artifacts from resolution, may be {@code null}. - * @return The list of artifacts denoting the resolved plugin class path, never {@code null}. + * @param dependencyFilter A filter to exclude artifacts from resolution (but not collection), may be {@code null}. + * @param repositories The plugin repositories to use for resolving the plugin artifacts, must not be {@code null}. + * @param session The repository session to use for resolving the plugin artifacts, must not be {@code null}. + * @return The dependency tree denoting the resolved plugin class path, never {@code null}. * @throws PluginResolutionException If any dependency could not be resolved. */ - List resolve( Plugin plugin, Artifact pluginArtifact, ArtifactResolutionRequest request, - ArtifactFilter dependencyFilter ) + DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter, + List repositories, RepositorySystemSession session ) throws PluginResolutionException; } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java new file mode 100644 index 0000000000..56b1c4f519 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java @@ -0,0 +1,109 @@ +package org.apache.maven.plugin.internal; + +/* + * 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. + */ + +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.collection.DependencyCollectionContext; +import org.sonatype.aether.collection.DependencySelector; +import org.sonatype.aether.graph.Dependency; + +/** + * Assists in detecting wagon providers brought into the plugin class path via legacy Maven core artifacts (e.g. + * maven-core:2.0.6) and excluding them. A plugin should be able to explicitly declare dependencies on specific wagons + * for its use. However, the (old) wagons pulled in transitively via legacy Maven core artifacts are usually not + * intended as dependencies and more importantly screw up artifact resolution because they would get preferred over the + * core wagon versions. This is a hack to provide backward-compat with Maven 2 (MNG-4528, MNG-4561). + * + * @author Benjamin Bentmann + */ +class WagonExcluder + implements DependencySelector +{ + + private final boolean coreArtifact; + + public WagonExcluder() + { + this( false ); + } + + private WagonExcluder( boolean coreArtifact ) + { + this.coreArtifact = coreArtifact; + } + + public boolean selectDependency( Dependency dependency ) + { + return !coreArtifact || !isWagonProvider( dependency.getArtifact() ); + } + + public DependencySelector deriveChildSelector( DependencyCollectionContext context ) + { + if ( coreArtifact || !isLegacyCoreArtifact( context.getDependency().getArtifact() ) ) + { + return this; + } + else + { + return new WagonExcluder( true ); + } + } + + private boolean isLegacyCoreArtifact( Artifact artifact ) + { + String version = artifact.getVersion(); + return version != null && version.startsWith( "2." ) && artifact.getArtifactId().startsWith( "maven-" ) + && artifact.getGroupId().equals( "org.apache.maven" ); + } + + private boolean isWagonProvider( Artifact artifact ) + { + if ( "org.apache.maven.wagon".equals( artifact.getGroupId() ) ) + { + return artifact.getArtifactId().startsWith( "wagon-" ); + } + return false; + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == this ) + { + return true; + } + else if ( obj == null || !getClass().equals( obj.getClass() ) ) + { + return false; + } + + WagonExcluder that = (WagonExcluder) obj; + return coreArtifact == that.coreArtifact; + } + + @Override + public int hashCode() + { + int hash = getClass().hashCode(); + hash = hash * 31 + ( coreArtifact ? 1 : 0 ); + return hash; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java index 5b4b2d0dd0..bcb1b757d2 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java @@ -19,17 +19,14 @@ * under the License. */ -import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.DefaultRepositoryRequest; -import org.apache.maven.artifact.repository.RepositoryCache; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.ArtifactTransferListener; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; /** * Collects settings required to resolve a plugin prefix. @@ -43,34 +40,25 @@ public class DefaultPluginPrefixRequest private String prefix; - private List pluginGroups; + private List pluginGroups = Collections.emptyList(); private Model pom; - private RepositoryRequest repositoryRequest; + private List repositories = Collections.emptyList(); + + private RepositorySystemSession session; /** * Creates an empty request. */ public DefaultPluginPrefixRequest() { - repositoryRequest = new DefaultRepositoryRequest(); - } - - /** - * Creates a request by copying settings from the specified repository request. - * - * @param repositoryRequest The repository request to copy from, must not be {@code null}. - */ - public DefaultPluginPrefixRequest( RepositoryRequest repositoryRequest ) - { - this.repositoryRequest = new DefaultRepositoryRequest( repositoryRequest ); } /** * Creates a request for the specified plugin prefix and build session. The provided build session will be used to - * configure repository settings. If the session has a current project, its plugin artifact repositories and model - * will be used as well. + * configure repository settings. If the session has a current project, its plugin repositories and model will be + * used as well. * * @param prefix The plugin prefix to resolve, must not be {@code null}. * @param session The build session from which to derive further settings, must not be {@code null}. @@ -79,18 +67,12 @@ public DefaultPluginPrefixRequest( String prefix, MavenSession session ) { setPrefix( prefix ); - this.repositoryRequest = new DefaultRepositoryRequest(); - - setCache( session.getRepositoryCache() ); - setLocalRepository( session.getLocalRepository() ); - setOffline( session.isOffline() ); - setForceUpdate( session.getRequest().isUpdateSnapshots() ); - setTransferListener( session.getRequest().getTransferListener() ); + setRepositorySession( session.getRepositorySession() ); MavenProject project = session.getCurrentProject(); if ( project != null ) { - setRemoteRepositories( project.getPluginArtifactRepositories() ); + setRepositories( project.getRemotePluginRepositories() ); setPom( project.getModel() ); } @@ -111,17 +93,19 @@ public DefaultPluginPrefixRequest setPrefix( String prefix ) public List getPluginGroups() { - if ( pluginGroups == null ) - { - pluginGroups = new ArrayList(); - } - return pluginGroups; } public DefaultPluginPrefixRequest setPluginGroups( List pluginGroups ) { - this.pluginGroups = pluginGroups; + if ( pluginGroups != null ) + { + this.pluginGroups = pluginGroups; + } + else + { + this.pluginGroups = Collections.emptyList(); + } return this; } @@ -138,74 +122,33 @@ public DefaultPluginPrefixRequest setPom( Model pom ) return this; } - public RepositoryCache getCache() + public List getRepositories() { - return repositoryRequest.getCache(); + return repositories; } - public DefaultPluginPrefixRequest setCache( RepositoryCache cache ) + public DefaultPluginPrefixRequest setRepositories( List repositories ) { - repositoryRequest.setCache( cache ); + if ( repositories != null ) + { + this.repositories = repositories; + } + else + { + this.repositories = Collections.emptyList(); + } return this; } - public ArtifactRepository getLocalRepository() + public RepositorySystemSession getRepositorySession() { - return repositoryRequest.getLocalRepository(); + return session; } - public DefaultPluginPrefixRequest setLocalRepository( ArtifactRepository localRepository ) + public DefaultPluginPrefixRequest setRepositorySession( RepositorySystemSession session ) { - repositoryRequest.setLocalRepository( localRepository ); - - return this; - } - - public List getRemoteRepositories() - { - return repositoryRequest.getRemoteRepositories(); - } - - public DefaultPluginPrefixRequest setRemoteRepositories( List remoteRepositories ) - { - repositoryRequest.setRemoteRepositories( remoteRepositories ); - - return this; - } - - public boolean isOffline() - { - return repositoryRequest.isOffline(); - } - - public DefaultPluginPrefixRequest setOffline( boolean offline ) - { - repositoryRequest.setOffline( offline ); - - return this; - } - - public boolean isForceUpdate() - { - return repositoryRequest.isForceUpdate(); - } - - public DefaultPluginPrefixRequest setForceUpdate( boolean forceUpdate ) - { - repositoryRequest.setForceUpdate( forceUpdate ); - - return this; - } - - public ArtifactTransferListener getTransferListener() - { - return repositoryRequest.getTransferListener(); - } - - public DefaultPluginPrefixRequest setTransferListener( ArtifactTransferListener transferListener ) - { - repositoryRequest.setTransferListener( transferListener ); + this.session = session; return this; } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java index d1f22310d3..7b868d8c5b 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java @@ -21,29 +21,21 @@ import java.util.List; -import org.apache.maven.artifact.repository.ArtifactRepository; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.RemoteRepository; public class NoPluginFoundForPrefixException extends Exception { - private String prefix; - - private ArtifactRepository localRepository; - - private List remoteRepositories; - - public NoPluginFoundForPrefixException( String prefix, List pluginGroups, - ArtifactRepository localRepository, - List remoteRepositories ) + + public NoPluginFoundForPrefixException( String prefix, List pluginGroups, LocalRepository localRepository, + List remoteRepositories ) { super( "No plugin found for prefix '" + prefix + "' in the current project and in the plugin groups " + pluginGroups + " available from the repositories " + format( localRepository, remoteRepositories ) ); - this.prefix = prefix; - this.localRepository = localRepository; - this.remoteRepositories = remoteRepositories; } - private static String format( ArtifactRepository localRepository, List remoteRepositories ) + private static String format( LocalRepository localRepository, List remoteRepositories ) { String repos = "["; @@ -54,7 +46,7 @@ private static String format( ArtifactRepository localRepository, List getRemoteRepositories(); + List getRepositories(); /** * Sets the remote repositories to use. Note: When creating a request from a project, be sure to use the - * plugin artifact repositories and not the regular artifact repositories. + * plugin repositories and not the regular project repositories. * - * @param remoteRepositories The remote repositories to use. + * @param repositories The remote repositories to use. * @return This request, never {@code null}. */ - PluginPrefixRequest setRemoteRepositories( List remoteRepositories ); + PluginPrefixRequest setRepositories( List repositories ); /** - * Gets the repository cache to use. + * Gets the session to use for repository access. * - * @return The repository cache to use or {@code null} if none. + * @return The repository session or {@code null} if not set. */ - RepositoryCache getCache(); + RepositorySystemSession getRepositorySession(); /** - * Sets the repository cache to use. + * Sets the session to use for repository access. * - * @param cache The repository cache to use, may be {@code null}. + * @param repositorySession The repository session to use. * @return This request, never {@code null}. */ - PluginPrefixRequest setCache( RepositoryCache cache ); - - /** - * Gets the listener to notify of transfer events. - * - * @return The transfer listener or {@code null} if none. - */ - ArtifactTransferListener getTransferListener(); - - /** - * Sets the listener to notify of transfer events. - * - * @param transferListener The transfer listener to notify, may be {@code null}. - * @return This request, never {@code null}. - */ - PluginPrefixRequest setTransferListener( ArtifactTransferListener transferListener ); + PluginPrefixRequest setRepositorySession( RepositorySystemSession repositorySession ); } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java index 6c95c17e20..44608ab9e5 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java @@ -1,5 +1,7 @@ package org.apache.maven.plugin.prefix; +import org.sonatype.aether.repository.ArtifactRepository; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -19,8 +21,6 @@ * under the License. */ -import org.apache.maven.artifact.repository.ArtifactRepository; - /** * Describes the result of a plugin prefix resolution request. * diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java index d74bc8ed4b..223d096ea1 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java @@ -23,11 +23,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.metadata.Metadata; import org.apache.maven.artifact.repository.metadata.io.MetadataReader; import org.apache.maven.model.Build; @@ -38,12 +36,18 @@ import org.apache.maven.plugin.prefix.PluginPrefixRequest; import org.apache.maven.plugin.prefix.PluginPrefixResolver; import org.apache.maven.plugin.prefix.PluginPrefixResult; -import org.apache.maven.repository.RepositorySystem; -import org.apache.maven.repository.ArtifactDoesNotExistException; -import org.apache.maven.repository.ArtifactTransferFailedException; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.repository.ArtifactRepository; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.RepositoryPolicy; +import org.sonatype.aether.resolution.MetadataRequest; +import org.sonatype.aether.resolution.MetadataResult; +import org.sonatype.aether.transfer.MetadataNotFoundException; +import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.sonatype.aether.util.metadata.DefaultMetadata; /** * Resolves a plugin prefix. @@ -56,6 +60,8 @@ public class DefaultPluginPrefixResolver implements PluginPrefixResolver { + private static final String REPOSITORY_CONTEXT = "plugin"; + @Requirement private Logger logger; @@ -82,8 +88,8 @@ public PluginPrefixResult resolve( PluginPrefixRequest request ) if ( result == null ) { throw new NoPluginFoundForPrefixException( request.getPrefix(), request.getPluginGroups(), - request.getLocalRepository(), - request.getRemoteRepositories() ); + request.getRepositorySession().getLocalRepository(), + request.getRepositories() ); } else if ( logger.isDebugEnabled() ) { @@ -126,7 +132,8 @@ private PluginPrefixResult resolveFromProject( PluginPrefixRequest request, List { try { - PluginDescriptor pluginDescriptor = pluginManager.loadPlugin( plugin, request ); + PluginDescriptor pluginDescriptor = + pluginManager.loadPlugin( plugin, request.getRepositories(), request.getRepositorySession() ); if ( request.getPrefix().equals( pluginDescriptor.getGoalPrefix() ) ) { @@ -152,155 +159,105 @@ private PluginPrefixResult resolveFromProject( PluginPrefixRequest request, List private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request ) { - ArtifactRepository localRepository = request.getLocalRepository(); + List requests = new ArrayList(); - // Process all plugin groups in the local repository first to see if we get a hit. A developer may have been - // developing a plugin locally and installing. - // for ( String pluginGroup : request.getPluginGroups() ) { - String localPath = getLocalMetadataPath( pluginGroup, localRepository ); + org.sonatype.aether.metadata.Metadata metadata = + new DefaultMetadata( pluginGroup, "maven-metadata.xml", DefaultMetadata.Nature.RELEASE_OR_SNAPSHOT ); - File groupMetadataFile = new File( localRepository.getBasedir(), localPath ); + requests.add( new MetadataRequest( metadata, null, REPOSITORY_CONTEXT ) ); - PluginPrefixResult result = - resolveFromRepository( request, pluginGroup, groupMetadataFile, localRepository ); - - if ( result != null ) + for ( RemoteRepository repository : request.getRepositories() ) { - return result; + requests.add( new MetadataRequest( metadata, repository, REPOSITORY_CONTEXT ) ); } } - Map> recheck = new HashMap>(); + // initial try, use locally cached metadata - // Process all the remote repositories. - // - for ( String pluginGroup : request.getPluginGroups() ) + List results = repositorySystem.resolveMetadata( request.getRepositorySession(), requests ); + requests.clear(); + + PluginPrefixResult result = processResults( request, results, requests ); + + if ( result != null ) { - for ( ArtifactRepository repository : request.getRemoteRepositories() ) + return result; + } + + // second try, refetch all (possibly outdated) metadata that wasn't updated in the first attempt + + if ( !request.getRepositorySession().isOffline() && !requests.isEmpty() ) + { + DefaultRepositorySystemSession session = + new DefaultRepositorySystemSession( request.getRepositorySession() ); + session.setUpdatePolicy( RepositoryPolicy.UPDATE_POLICY_ALWAYS ); + + results = repositorySystem.resolveMetadata( session, requests ); + + return processResults( request, results, null ); + } + + return null; + } + + private PluginPrefixResult processResults( PluginPrefixRequest request, List results, + List requests ) + { + for ( MetadataResult res : results ) + { + if ( res.getException() != null ) { - if ( !isEnabled( repository ) ) + if ( res.getException() instanceof MetadataNotFoundException ) { - logger.debug( "Skipped plugin prefix lookup from disabled repository " + repository.getId() ); - continue; + logger.debug( "Could not find " + res.getRequest().getMetadata() + " in " + + res.getRequest().getRepository() ); + } + else if ( logger.isDebugEnabled() ) + { + logger.warn( "Could not retrieve " + res.getRequest().getMetadata() + " from " + + res.getRequest().getRepository() + ": " + res.getException().getMessage(), res.getException() ); + } + else + { + logger.warn( "Could not retrieve " + res.getRequest().getMetadata() + " from " + + res.getRequest().getRepository() + ": " + res.getException().getMessage() ); + } + } + + org.sonatype.aether.metadata.Metadata metadata = res.getMetadata(); + + if ( metadata != null ) + { + ArtifactRepository repository = res.getRequest().getRepository(); + if ( repository == null ) + { + repository = request.getRepositorySession().getLocalRepository(); } - String localPath = getLocalMetadataPath( pluginGroup, repository ); - - File groupMetadataFile = new File( localRepository.getBasedir(), localPath ); - - if ( !request.isOffline() && ( !groupMetadataFile.exists() || request.isForceUpdate() ) ) - { - String remotePath = getRemoteMetadataPath( pluginGroup, repository ); - - try - { - repositorySystem.retrieve( repository, groupMetadataFile, remotePath, - request.getTransferListener() ); - } - catch ( ArtifactTransferFailedException e ) - { - if ( logger.isDebugEnabled() ) - { - logger.warn( "Failed to retrieve " + remotePath + " from " + repository.getId() + ": " - + e.getMessage(), e ); - } - else - { - logger.warn( "Failed to retrieve " + remotePath + " from " + repository.getId() + ": " - + e.getMessage() ); - } - } - catch ( ArtifactDoesNotExistException e ) - { - continue; - } - } - else if ( !request.isOffline() && !request.isForceUpdate() ) - { - List repos = recheck.get( pluginGroup ); - if ( repos == null ) - { - repos = new ArrayList(); - recheck.put( pluginGroup, repos ); - } - repos.add( repository ); - } - - PluginPrefixResult result = resolveFromRepository( request, pluginGroup, groupMetadataFile, - repository ); + PluginPrefixResult result = + resolveFromRepository( request, metadata.getGroupId(), metadata.getFile(), repository ); if ( result != null ) { return result; } } - } - // Retry the remote repositories for which we previously only consulted the possibly outdated local cache. - // - for ( String pluginGroup : request.getPluginGroups() ) - { - List repos = recheck.get( pluginGroup ); - if ( repos == null ) + if ( requests != null && !res.isUpdated() ) { - continue; - } - - for ( ArtifactRepository repository : repos ) - { - String localPath = getLocalMetadataPath( pluginGroup, repository ); - - File groupMetadataFile = new File( localRepository.getBasedir(), localPath ); - - String remotePath = getRemoteMetadataPath( pluginGroup, repository ); - - try - { - repositorySystem.retrieve( repository, groupMetadataFile, remotePath, - request.getTransferListener() ); - } - catch ( ArtifactTransferFailedException e ) - { - if ( logger.isDebugEnabled() ) - { - logger.warn( "Failed to retrieve " + remotePath + " from " + repository.getId() + ": " - + e.getMessage(), e ); - } - else - { - logger.warn( "Failed to retrieve " + remotePath + " from " + repository.getId() + ": " - + e.getMessage() ); - } - } - catch ( ArtifactDoesNotExistException e ) - { - continue; - } - - PluginPrefixResult result = resolveFromRepository( request, pluginGroup, groupMetadataFile, - repository ); - - if ( result != null ) - { - return result; - } + requests.add( res.getRequest() ); } } return null; } - private boolean isEnabled( ArtifactRepository repository ) - { - return repository.getReleases().isEnabled() || repository.getSnapshots().isEnabled(); - } - private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request, String pluginGroup, File metadataFile, ArtifactRepository repository ) { - if ( metadataFile.isFile() ) + if ( metadataFile != null && metadataFile.isFile() ) { try { @@ -337,14 +294,4 @@ private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request, S return null; } - private String getLocalMetadataPath( String groupId, ArtifactRepository repository ) - { - return groupId.replace( '.', '/' ) + "/" + "maven-metadata-" + repository.getId() + ".xml"; - } - - private String getRemoteMetadataPath( String groupId, ArtifactRepository repository ) - { - return groupId.replace( '.', '/' ) + "/" + "maven-metadata.xml"; - } - } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java index b787f6a16f..048c87abcb 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java @@ -19,9 +19,9 @@ * under the License. */ -import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.prefix.PluginPrefixResult; +import org.sonatype.aether.repository.ArtifactRepository; /** * Describes the result of a plugin prefix resolution request. diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java index 7e595d0576..7f95e27dff 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java @@ -19,17 +19,15 @@ * under the License. */ +import java.util.Collections; import java.util.List; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.DefaultRepositoryRequest; -import org.apache.maven.artifact.repository.RepositoryCache; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.ArtifactTransferListener; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; /** * Collects settings required to resolve the version for a plugin. @@ -47,65 +45,55 @@ public class DefaultPluginVersionRequest private Model pom; - private RepositoryRequest repositoryRequest; + private List repositories = Collections.emptyList(); + + private RepositorySystemSession session; /** * Creates an empty request. */ public DefaultPluginVersionRequest() { - repositoryRequest = new DefaultRepositoryRequest(); - } - - /** - * Creates a request by copying settings from the specified repository request. - * - * @param repositoryRequest The repository request to copy from, must not be {@code null}. - */ - public DefaultPluginVersionRequest( RepositoryRequest repositoryRequest ) - { - this.repositoryRequest = new DefaultRepositoryRequest( repositoryRequest ); - } - - /** - * Creates a request for the specified plugin by copying settings from the specified repository request. - * - * @param The plugin for which to resolve a version, must not be {@code null}. - * @param repositoryRequest The repository request to copy from, must not be {@code null}. - */ - public DefaultPluginVersionRequest( Plugin plugin, RepositoryRequest repositoryRequest ) - { - this.groupId = plugin.getGroupId(); - this.artifactId = plugin.getArtifactId(); - this.repositoryRequest = new DefaultRepositoryRequest( repositoryRequest ); } /** * Creates a request for the specified plugin by copying settings from the specified build session. If the session - * has a current project, its plugin artifact repositories will be used as well. + * has a current project, its plugin repositories will be used as well. * - * @param The plugin for which to resolve a version, must not be {@code null}. + * @param plugin The plugin for which to resolve a version, must not be {@code null}. * @param repositoryRequest The repository request to copy from, must not be {@code null}. */ public DefaultPluginVersionRequest( Plugin plugin, MavenSession session ) { - this.groupId = plugin.getGroupId(); - this.artifactId = plugin.getArtifactId(); - this.repositoryRequest = new DefaultRepositoryRequest(); + setGroupId( plugin.getGroupId() ); + setArtifactId( plugin.getArtifactId() ); - setCache( session.getRepositoryCache() ); - setLocalRepository( session.getLocalRepository() ); - setOffline( session.isOffline() ); - setForceUpdate( session.getRequest().isUpdateSnapshots() ); - setTransferListener( session.getRequest().getTransferListener() ); + setRepositorySession( session.getRepositorySession() ); MavenProject project = session.getCurrentProject(); if ( project != null ) { - setRemoteRepositories( project.getPluginArtifactRepositories() ); + setRepositories( project.getRemotePluginRepositories() ); } } + /** + * Creates a request for the specified plugin using the given repository session and plugin repositories. + * + * @param plugin The plugin for which to resolve a version, must not be {@code null}. + * @param session The repository session to use, must not be {@code null}. + * @param repositories The plugin repositories to query, may be {@code null}. + */ + public DefaultPluginVersionRequest( Plugin plugin, RepositorySystemSession session, List repositories ) + { + setGroupId( plugin.getGroupId() ); + setArtifactId( plugin.getArtifactId() ); + + setRepositorySession( session ); + + setRepositories( repositories ); + } + public String getGroupId() { return groupId; @@ -142,74 +130,33 @@ public DefaultPluginVersionRequest setPom( Model pom ) return this; } - public RepositoryCache getCache() + public List getRepositories() { - return repositoryRequest.getCache(); + return repositories; } - public DefaultPluginVersionRequest setCache( RepositoryCache cache ) + public DefaultPluginVersionRequest setRepositories( List repositories ) { - repositoryRequest.setCache( cache ); + if ( repositories != null ) + { + this.repositories = repositories; + } + else + { + this.repositories = Collections.emptyList(); + } return this; } - public ArtifactRepository getLocalRepository() + public RepositorySystemSession getRepositorySession() { - return repositoryRequest.getLocalRepository(); + return session; } - public DefaultPluginVersionRequest setLocalRepository( ArtifactRepository localRepository ) + public DefaultPluginVersionRequest setRepositorySession( RepositorySystemSession session ) { - repositoryRequest.setLocalRepository( localRepository ); - - return this; - } - - public List getRemoteRepositories() - { - return repositoryRequest.getRemoteRepositories(); - } - - public DefaultPluginVersionRequest setRemoteRepositories( List remoteRepositories ) - { - repositoryRequest.setRemoteRepositories( remoteRepositories ); - - return this; - } - - public boolean isOffline() - { - return repositoryRequest.isOffline(); - } - - public DefaultPluginVersionRequest setOffline( boolean offline ) - { - repositoryRequest.setOffline( offline ); - - return this; - } - - public boolean isForceUpdate() - { - return repositoryRequest.isForceUpdate(); - } - - public DefaultPluginVersionRequest setForceUpdate( boolean forceUpdate ) - { - repositoryRequest.setForceUpdate( forceUpdate ); - - return this; - } - - public ArtifactTransferListener getTransferListener() - { - return repositoryRequest.getTransferListener(); - } - - public DefaultPluginVersionRequest setTransferListener( ArtifactTransferListener transferListener ) - { - repositoryRequest.setTransferListener( transferListener ); + this.session = session; return this; } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java index acbb9b5d26..f887265195 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java @@ -21,11 +21,9 @@ import java.util.List; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.RepositoryCache; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.model.Model; -import org.apache.maven.repository.ArtifactTransferListener; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; /** * Collects settings required to resolve the version for a plugin. @@ -34,7 +32,6 @@ * @author Benjamin Bentmann */ public interface PluginVersionRequest - extends RepositoryRequest { /** @@ -84,80 +81,35 @@ public interface PluginVersionRequest */ PluginVersionRequest setPom( Model pom ); - /** - * Indicates whether network access to remote repositories has been disabled. - * - * @return {@code true} if remote access has been disabled, {@code false} otherwise. - */ - boolean isOffline(); - - /** - * Enables/disables network access to remote repositories. - * - * @param offline {@code true} to disable remote access, {@code false} to allow network access. - * @return This request, never {@code null}. - */ - PluginVersionRequest setOffline( boolean offline ); - - /** - * Gets the local repository to use. - * - * @return The local repository to use or {@code null} if not set. - */ - ArtifactRepository getLocalRepository(); - - /** - * Sets the local repository to use. - * - * @param localRepository The local repository to use. - * @return This request, never {@code null}. - */ - PluginVersionRequest setLocalRepository( ArtifactRepository localRepository ); - /** * Gets the remote repositories to use. * * @return The remote repositories to use, never {@code null}. */ - List getRemoteRepositories(); + List getRepositories(); /** * Sets the remote repositories to use. Note: When creating a request from a project, be sure to use the - * plugin artifact repositories and not the regular artifact repositories. + * plugin repositories and not the regular project repositories. * - * @param remoteRepositories The remote repositories to use. + * @param repositories The remote repositories to use. * @return This request, never {@code null}. */ - PluginVersionRequest setRemoteRepositories( List remoteRepositories ); + PluginVersionRequest setRepositories( List repositories ); /** - * Gets the repository cache to use. + * Gets the session to use for repository access. * - * @return The repository cache to use or {@code null} if none. + * @return The repository session or {@code null} if not set. */ - RepositoryCache getCache(); + RepositorySystemSession getRepositorySession(); /** - * Sets the repository cache to use. + * Sets the session to use for repository access. * - * @param cache The repository cache to use, may be {@code null}. + * @param repositorySession The repository session to use. * @return This request, never {@code null}. */ - PluginVersionRequest setCache( RepositoryCache cache ); - - /** - * Gets the listener to notify of transfer events. - * - * @return The transfer listener or {@code null} if none. - */ - ArtifactTransferListener getTransferListener(); - - /** - * Sets the listener to notify of transfer events. - * - * @param transferListener The transfer listener to notify, may be {@code null}. - * @return This request, never {@code null}. - */ - PluginVersionRequest setTransferListener( ArtifactTransferListener transferListener ); + PluginVersionRequest setRepositorySession( RepositorySystemSession repositorySession ); } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java b/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java index 719b204439..af85f1f7ac 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java @@ -21,7 +21,8 @@ import java.util.List; -import org.apache.maven.artifact.repository.ArtifactRepository; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.RemoteRepository; public class PluginVersionResolutionException extends Exception @@ -50,8 +51,8 @@ public PluginVersionResolutionException( String groupId, String artifactId, Stri this.baseMessage = baseMessage; } - public PluginVersionResolutionException( String groupId, String artifactId, ArtifactRepository localRepository, - List remoteRepositories, String baseMessage ) + public PluginVersionResolutionException( String groupId, String artifactId, LocalRepository localRepository, + List remoteRepositories, String baseMessage ) { super( "Error resolving version for plugin \'" + groupId + ":" + artifactId + "\' from the repositories " + format( localRepository, remoteRepositories ) + ": " + baseMessage ); @@ -76,7 +77,7 @@ public String getBaseMessage() return baseMessage; } - private static String format( ArtifactRepository localRepository, List remoteRepositories ) + private static String format( LocalRepository localRepository, List remoteRepositories ) { String repos = "["; @@ -87,7 +88,7 @@ private static String format( ArtifactRepository localRepository, List requests = new ArrayList(); - // Search in remote repositories for a (released) version. - // - // maven-metadata-{central|nexus|...}.xml - // - // TODO: we should cycle through the repositories but take the repository which actually satisfied the prefix. - for ( ArtifactRepository repository : request.getRemoteRepositories() ) + requests.add( new MetadataRequest( metadata, null, REPOSITORY_CONTEXT ) ); + + for ( RemoteRepository repository : request.getRepositories() ) { - if ( !isEnabled( repository ) ) + requests.add( new MetadataRequest( metadata, repository, REPOSITORY_CONTEXT ) ); + } + + List results = metadataResolver.resolveMetadata( request.getRepositorySession(), requests ); + + LocalRepository localRepo = request.getRepositorySession().getLocalRepository(); + + Versions versions = new Versions(); + + for ( MetadataResult res : results ) + { + if ( res.getException() != null ) { - logger.debug( "Skipped plugin version lookup from disabled repository " + repository.getId() ); - continue; - } - - String localPath = getLocalMetadataPath( request, repository ); - - File artifactMetadataFile = new File( localRepository.getBasedir(), localPath ); - - if ( !request.isOffline() && ( !artifactMetadataFile.exists() /* || user requests snapshot updates */ ) ) - { - String remotePath = getRemoteMetadataPath( request, repository ); - - try + if ( res.getException() instanceof MetadataNotFoundException ) { - repositorySystem.retrieve( repository, artifactMetadataFile, remotePath, - request.getTransferListener() ); + logger.debug( "Could not find " + res.getRequest().getMetadata() + " in " + + res.getRequest().getRepository() ); } - catch ( ArtifactTransferFailedException e ) + else if ( logger.isDebugEnabled() ) { - if ( logger.isDebugEnabled() ) - { - logger.warn( "Failed to retrieve " + remotePath + " from " + repository.getId() + ": " - + e.getMessage(), e ); - } - else - { - logger.warn( "Failed to retrieve " + remotePath + " from " + repository.getId() + ": " - + e.getMessage() ); - } - - continue; + logger.warn( "Could not retrieve " + res.getRequest().getMetadata() + " from " + + res.getRequest().getRepository() + ": " + res.getException().getMessage(), res.getException() ); } - catch ( ArtifactDoesNotExistException e ) + else { - continue; + logger.warn( "Could not retrieve " + res.getRequest().getMetadata() + " from " + + res.getRequest().getRepository() + ": " + res.getException().getMessage() ); } } - if ( mergeMetadata( mergedMetadata, artifactMetadataFile ) ) + if ( res.getMetadata() != null ) { - result.setRepository( repository ); + mergeMetadata( versions, res.getMetadata().getFile(), res.getRequest().getRepository() ); } } - // Search in the local repositiory for a (development) version - // - // maven-metadata-local.xml - // + if ( StringUtils.isNotEmpty( versions.releaseVersion ) ) { - String localPath = getLocalMetadataPath( request, localRepository ); - - File artifactMetadataFile = new File( localRepository.getBasedir(), localPath ); - - if ( mergeMetadata( mergedMetadata, artifactMetadataFile ) ) - { - result.setRepository( localRepository ); - } + result.setVersion( versions.releaseVersion ); + result.setRepository( ( versions.releaseRepository == null ) ? localRepo : versions.releaseRepository ); } - - if ( mergedMetadata.getVersioning() != null ) + else if ( StringUtils.isNotEmpty( versions.latestVersion ) ) { - String release = mergedMetadata.getVersioning().getRelease(); - - if ( StringUtils.isNotEmpty( release ) ) - { - result.setVersion( release ); - } - else - { - String latest = mergedMetadata.getVersioning().getLatest(); - - if ( StringUtils.isNotEmpty( latest ) ) - { - result.setVersion( latest ); - } - } + result.setVersion( versions.latestVersion ); + result.setRepository( ( versions.latestRepository == null ) ? localRepo : versions.latestRepository ); } - - if ( StringUtils.isEmpty( result.getVersion() ) ) + else { - throw new PluginVersionResolutionException( request.getGroupId(), request.getArtifactId(), - request.getLocalRepository(), request.getRemoteRepositories(), + throw new PluginVersionResolutionException( request.getGroupId(), request.getArtifactId(), localRepo, + request.getRepositories(), "Plugin not found in any plugin repository" ); } return result; } - private boolean isEnabled( ArtifactRepository repository ) + private void mergeMetadata( Versions versions, File metadataFile, ArtifactRepository repository ) { - return repository.getReleases().isEnabled() || repository.getSnapshots().isEnabled(); - } - - private String getLocalMetadataPath( PluginVersionRequest request, ArtifactRepository repository ) - { - return request.getGroupId().replace( '.', '/' ) + '/' + request.getArtifactId() + "/maven-metadata-" - + repository.getId() + ".xml"; - } - - private String getRemoteMetadataPath( PluginVersionRequest request, ArtifactRepository repository ) - { - return request.getGroupId().replace( '.', '/' ) + '/' + request.getArtifactId() + "/maven-metadata.xml"; - } - - private boolean mergeMetadata( Metadata target, File metadataFile ) - { - if ( metadataFile.isFile() ) + if ( metadataFile != null && metadataFile.isFile() ) { try { @@ -228,7 +177,7 @@ private boolean mergeMetadata( Metadata target, File metadataFile ) Metadata repoMetadata = metadataReader.read( metadataFile, options ); - return mergeMetadata( target, repoMetadata ); + mergeMetadata( versions, repoMetadata, repository ); } catch ( IOException e ) { @@ -242,13 +191,31 @@ private boolean mergeMetadata( Metadata target, File metadataFile ) } } } - - return false; } - private boolean mergeMetadata( Metadata target, Metadata source ) + private void mergeMetadata( Versions versions, Metadata source, ArtifactRepository repository ) { - return target.merge( source ); + Versioning versioning = source.getVersioning(); + if ( versioning != null ) + { + String timestamp = StringUtils.clean( versioning.getLastUpdated() ); + + if ( StringUtils.isNotEmpty( versioning.getRelease() ) + && timestamp.compareTo( versions.releaseTimestamp ) > 0 ) + { + versions.releaseVersion = versioning.getRelease(); + versions.releaseTimestamp = timestamp; + versions.releaseRepository = repository; + } + + if ( StringUtils.isNotEmpty( versioning.getLatest() ) + && timestamp.compareTo( versions.latestTimestamp ) > 0 ) + { + versions.latestVersion = versioning.getLatest(); + versions.latestTimestamp = timestamp; + versions.latestRepository = repository; + } + } } private PluginVersionResult resolveFromProject( PluginVersionRequest request ) @@ -290,4 +257,21 @@ private PluginVersionResult resolveFromProject( PluginVersionRequest request, Li return null; } + static class Versions + { + + String releaseVersion = ""; + + String releaseTimestamp = ""; + + ArtifactRepository releaseRepository; + + String latestVersion = ""; + + String latestTimestamp = ""; + + ArtifactRepository latestRepository; + + } + } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java b/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java index db63b52e5e..a26f110fe1 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java @@ -19,8 +19,8 @@ * under the License. */ -import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.version.PluginVersionResult; +import org.sonatype.aether.repository.ArtifactRepository; /** * Describes the result of a plugin version resolution request. diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java b/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java new file mode 100644 index 0000000000..a7f3a93812 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java @@ -0,0 +1,82 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.graph.DependencyFilter; + +/** + * @author Benjamin Bentmann + */ +public class DefaultDependencyResolutionRequest + implements DependencyResolutionRequest +{ + + private MavenProject project; + + private DependencyFilter filter; + + private RepositorySystemSession session; + + public DefaultDependencyResolutionRequest() + { + // enables default constructor + } + + public DefaultDependencyResolutionRequest( MavenProject project, RepositorySystemSession session ) + { + setMavenProject( project ); + setRepositorySession( session ); + } + + public DependencyFilter getResolutionFilter() + { + return filter; + } + + public MavenProject getMavenProject() + { + return project; + } + + public RepositorySystemSession getRepositorySession() + { + return session; + } + + public DependencyResolutionRequest setResolutionFilter( DependencyFilter filter ) + { + this.filter = filter; + return this; + } + + public DependencyResolutionRequest setMavenProject( MavenProject project ) + { + this.project = project; + return this; + } + + public DependencyResolutionRequest setRepositorySession( RepositorySystemSession repositorySession ) + { + this.session = repositorySession; + return this; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java b/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java new file mode 100644 index 0000000000..1a97b570d6 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java @@ -0,0 +1,111 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; + +import org.sonatype.aether.graph.Dependency; +import org.sonatype.aether.graph.DependencyNode; + +/** + * @author Benjamin Bentmann + */ +class DefaultDependencyResolutionResult + implements DependencyResolutionResult +{ + + private DependencyNode root; + + private List dependencies = new ArrayList(); + + private List resolvedDependencies = new ArrayList(); + + private List unresolvedDependencies = new ArrayList(); + + private List collectionErros = new ArrayList(); + + private Map> resolutionErrors = new IdentityHashMap>(); + + public DependencyNode getDependencyGraph() + { + return root; + } + + public void setDependencyGraph( DependencyNode root ) + { + this.root = root; + } + + public List getDependencies() + { + return dependencies; + } + + public List getResolvedDependencies() + { + return resolvedDependencies; + } + + public void addResolvedDependency( Dependency dependency ) + { + dependencies.add( dependency ); + resolvedDependencies.add( dependency ); + } + + public List getUnresolvedDependencies() + { + return unresolvedDependencies; + } + + public List getCollectionErrors() + { + return collectionErros; + } + + public void setCollectionErrors( List exceptions ) + { + if ( exceptions != null ) + { + this.collectionErros = exceptions; + } + else + { + this.collectionErros = new ArrayList(); + } + } + + public List getResolutionErrors( Dependency dependency ) + { + List errors = resolutionErrors.get( dependency ); + return ( errors != null ) ? errors : Collections. emptyList(); + } + + public void setResolutionErrors( Dependency dependency, List errors ) + { + dependencies.add( dependency ); + unresolvedDependencies.add( dependency ); + resolutionErrors.put( dependency, errors ); + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java b/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java index f7d4cfea26..baaf01ef2b 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java @@ -107,7 +107,7 @@ public void buildExtensionsAssembled( ModelBuildingEvent event ) projectBuildingHelper.createProjectRealm( project, model, projectBuildingRequest ); project.setClassRealm( record.realm ); - project.setExtensionArtifactFilter( record.extensionArtifactFilter ); + project.setExtensionDependencyFilter( record.extensionArtifactFilter ); } catch ( PluginResolutionException e ) { diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java index b0a2daaf11..1c4a63f41d 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java @@ -1,35 +1,30 @@ package org.apache.maven.project; /* - * 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. + * 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. */ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; -import org.apache.maven.artifact.resolver.ResolutionErrorHandler; import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Profile; @@ -45,18 +40,23 @@ import org.apache.maven.model.building.ModelSource; import org.apache.maven.model.building.StringModelSource; import org.apache.maven.model.resolution.ModelResolver; -import org.apache.maven.project.artifact.ProjectArtifact; import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.Os; import org.codehaus.plexus.util.StringUtils; +import org.sonatype.aether.impl.ArtifactResolver; +import org.sonatype.aether.impl.RemoteRepositoryManager; +import org.sonatype.aether.repository.WorkspaceRepository; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.ArtifactResult; +import org.sonatype.aether.util.artifact.SubArtifact; /** * @version $Id$ */ -@Component( role = ProjectBuilder.class ) +@Component(role = ProjectBuilder.class) public class DefaultProjectBuilder implements ProjectBuilder { @@ -77,7 +77,13 @@ public class DefaultProjectBuilder private RepositorySystem repositorySystem; @Requirement - private ResolutionErrorHandler resolutionErrorHandler; + private ArtifactResolver artifactResolver; + + @Requirement + private RemoteRepositoryManager repositoryManager; + + @Requirement + private ProjectDependenciesResolver dependencyResolver; // ---------------------------------------------------------------------- // MavenProjectBuilder Implementation @@ -115,11 +121,11 @@ private ProjectBuildingResult build( File pomFile, ModelSource modelSource, Proj DefaultModelBuildingListener listener = new DefaultModelBuildingListener( project, projectBuildingHelper, configuration ); request.setModelBuildingListener( listener ); - + request.setPomFile( pomFile ); request.setModelSource( modelSource ); request.setLocationTracking( pomFile != null ); - + ModelBuildingResult result; try { @@ -139,34 +145,32 @@ else if ( configuration.isResolveDependencies() ) projectBuildingHelper.selectProjectRealm( project ); } - ArtifactResolutionResult artifactResult = null; + DependencyResolutionResult resolutionResult = null; if ( configuration.isResolveDependencies() ) { - Artifact artifact = new ProjectArtifact( project ); + try + { + DefaultDependencyResolutionRequest resolution = + new DefaultDependencyResolutionRequest( project, configuration.getRepositorySession() ); + resolutionResult = dependencyResolver.resolve( resolution ); + } + catch ( DependencyResolutionException e ) + { + resolutionResult = e.getResult(); + } - ArtifactResolutionRequest artifactRequest = new ArtifactResolutionRequest() - .setArtifact( artifact ) - .setResolveRoot( false ) - .setResolveTransitively( true ) - .setCache( configuration.getRepositoryCache() ) - .setLocalRepository( configuration.getLocalRepository() ) - .setRemoteRepositories( project.getRemoteArtifactRepositories() ) - .setServers( configuration.getServers() ) - .setMirrors( configuration.getMirrors() ) - .setProxies( configuration.getProxies() ) - .setOffline( configuration.isOffline() ) - .setForceUpdate( configuration.isForceUpdate() ) - .setManagedVersionMap( project.getManagedVersionMap() ); - artifactRequest.setTransferListener( configuration.getTransferListener() ); - - artifactResult = repositorySystem.resolve( artifactRequest ); - - project.setResolvedArtifacts( artifactResult.getArtifacts() ); - project.setArtifacts( artifactResult.getArtifacts() ); + Set artifacts = new LinkedHashSet(); + if ( resolutionResult.getDependencyGraph() != null ) + { + RepositoryUtils.toArtifacts( artifacts, resolutionResult.getDependencyGraph().getChildren(), + Collections.singletonList( project.getArtifact().getId() ), null ); + } + project.setResolvedArtifacts( artifacts ); + project.setArtifacts( artifacts ); } - return new DefaultProjectBuildingResult( project, modelProblems, artifactResult ); + return new DefaultProjectBuildingResult( project, modelProblems, resolutionResult ); } finally { @@ -187,10 +191,12 @@ private List getProfileIds( List profiles ) } private ModelBuildingRequest getModelBuildingRequest( ProjectBuildingRequest configuration, - ReactorModelPool reactorModelPool ) + ReactorModelPool modelPool ) { ModelResolver resolver = - new RepositoryModelResolver( repositorySystem, resolutionErrorHandler, configuration, reactorModelPool ); + new ReactorModelResolver( configuration.getRepositorySession(), artifactResolver, + repositoryManager, + RepositoryUtils.toRepos( configuration.getRemoteRepositories() ), modelPool ); ModelBuildingRequest request = new DefaultModelBuildingRequest(); @@ -216,42 +222,34 @@ public ProjectBuildingResult build( Artifact artifact, ProjectBuildingRequest co public ProjectBuildingResult build( Artifact artifact, boolean allowStubModel, ProjectBuildingRequest configuration ) throws ProjectBuildingException { - if ( !artifact.getType().equals( "pom" ) ) + org.sonatype.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact( artifact ); + if ( !pomArtifact.getExtension().equals( "pom" ) ) { - artifact = - repositorySystem.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(), - artifact.getVersion() ); - } - - ArtifactResolutionRequest request = new ArtifactResolutionRequest() - .setArtifact( artifact ) - .setCache( configuration.getRepositoryCache() ) - .setLocalRepository( configuration.getLocalRepository() ) - .setRemoteRepositories( configuration.getRemoteRepositories() ) - .setOffline( configuration.isOffline() ) - .setForceUpdate( configuration.isForceUpdate() ); - request.setTransferListener( configuration.getTransferListener() ); - - ArtifactResolutionResult result = repositorySystem.resolve( request ); - - if ( result.hasMissingArtifacts() && allowStubModel ) - { - return build( null, createStubModelSource( artifact ), configuration ); + pomArtifact = new SubArtifact( pomArtifact, "", "pom" ); } + ArtifactResult result; try { - resolutionErrorHandler.throwErrors( request, result ); + ArtifactRequest request = new ArtifactRequest(); + request.setArtifact( pomArtifact ); + request.setRepositories( RepositoryUtils.toRepos( configuration.getRemoteRepositories() ) ); + result = artifactResolver.resolveArtifact( configuration.getRepositorySession(), request ); + pomArtifact = result.getArtifact(); } - catch ( ArtifactResolutionException e ) + catch ( org.sonatype.aether.resolution.ArtifactResolutionException e ) { + if ( e.getResults().get( 0 ).isMissing() && allowStubModel ) + { + return build( null, createStubModelSource( artifact ), configuration ); + } throw new ProjectBuildingException( artifact.getId(), "Error resolving project artifact: " + e.getMessage(), e ); } - boolean localProject = artifact.getRepository() != null && artifact.getRepository().isProjectAware(); + boolean localProject = result.getRepository() instanceof WorkspaceRepository; - File pomFile = artifact.getFile(); + File pomFile = pomArtifact.getFile(); return build( localProject ? pomFile : null, new FileModelSource( pomFile ), configuration ); } @@ -279,14 +277,14 @@ public List build( List pomFiles, boolean recursive List interimResults = new ArrayList(); - ReactorModelPool reactorModelPool = new ReactorModelPool(); + ReactorModelPool modelPool = new ReactorModelPool(); ReactorModelCache modelCache = new ReactorModelCache(); boolean noErrors = - build( results, interimResults, pomFiles, true, recursive, config, reactorModelPool, modelCache ); + build( results, interimResults, pomFiles, true, recursive, config, modelPool, modelCache ); - populateReactorModelPool( reactorModelPool, interimResults ); + populateReactorModelPool( modelPool, interimResults ); ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader(); diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java index bebc42cf5f..c81e213e28 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java @@ -22,20 +22,16 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.DefaultRepositoryRequest; -import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter; import org.apache.maven.classrealm.ClassRealmManager; import org.apache.maven.model.Build; import org.apache.maven.model.Extension; @@ -56,10 +52,16 @@ import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.util.filter.ExclusionsDependencyFilter; +import org.sonatype.aether.util.graph.PreorderNodeListGenerator; /** * Assists the project builder. Warning: This is an internal utility class that is only public for - * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without + * technical reasons, it is not part of the public API. In particular, this class can be changed or deleted without * prior notice. * * @author Benjamin Bentmann @@ -104,10 +106,12 @@ public List createArtifactRepositories( List pom throws InvalidRepositoryException { List artifactRepositories = new ArrayList(); + Collection repoIds = new HashSet(); for ( Repository repository : pomRepositories ) { artifactRepositories.add( repositorySystem.buildArtifactRepository( repository ) ); + repoIds.add( repository.getId() ); } repositorySystem.injectMirror( artifactRepositories, request.getMirrors() ); @@ -118,7 +122,13 @@ public List createArtifactRepositories( List pom if ( externalRepositories != null ) { - artifactRepositories.addAll( externalRepositories ); + for ( ArtifactRepository repository : externalRepositories ) + { + if ( repoIds.add( repository.getId() ) ) + { + artifactRepositories.add( repository ); + } + } } artifactRepositories = repositorySystem.getEffectiveRepositories( artifactRepositories ); @@ -174,26 +184,23 @@ public synchronized ProjectRealmCache.CacheRecord createProjectRealm( MavenProje List publicArtifacts = new ArrayList(); - RepositoryRequest repositoryRequest = new DefaultRepositoryRequest(); - repositoryRequest.setCache( request.getRepositoryCache() ); - repositoryRequest.setLocalRepository( request.getLocalRepository() ); - repositoryRequest.setRemoteRepositories( project.getPluginArtifactRepositories() ); - repositoryRequest.setOffline( request.isOffline() ); - repositoryRequest.setForceUpdate( request.isForceUpdate() ); - repositoryRequest.setTransferListener( request.getTransferListener() ); - for ( Plugin plugin : extensionPlugins ) { if ( plugin.getVersion() == null ) { - PluginVersionRequest versionRequest = new DefaultPluginVersionRequest( plugin, repositoryRequest ); + PluginVersionRequest versionRequest = + new DefaultPluginVersionRequest( plugin, request.getRepositorySession(), + project.getRemotePluginRepositories() ); plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() ); } List artifacts; - PluginArtifactsCache.CacheRecord recordArtifacts = - pluginArtifactsCache.get( plugin, repositoryRequest, null ); + PluginArtifactsCache.Key cacheKey = + pluginArtifactsCache.createKey( plugin, null, project.getRemotePluginRepositories(), + request.getRepositorySession() ); + + PluginArtifactsCache.CacheRecord recordArtifacts = pluginArtifactsCache.get( cacheKey ); if ( recordArtifacts != null ) { @@ -201,9 +208,9 @@ public synchronized ProjectRealmCache.CacheRecord createProjectRealm( MavenProje } else { - artifacts = resolveExtensionArtifacts( plugin, repositoryRequest, request ); + artifacts = resolveExtensionArtifacts( plugin, project.getRemotePluginRepositories(), request ); - recordArtifacts = pluginArtifactsCache.put( plugin, repositoryRequest, null, artifacts ); + recordArtifacts = pluginArtifactsCache.put( cacheKey, artifacts ); } pluginArtifactsCache.register( project, recordArtifacts ); @@ -314,10 +321,10 @@ public synchronized ProjectRealmCache.CacheRecord createProjectRealm( MavenProje } } - ArtifactFilter extensionArtifactFilter = null; + DependencyFilter extensionArtifactFilter = null; if ( !exclusions.isEmpty() ) { - extensionArtifactFilter = new ExclusionSetFilter( exclusions ); + extensionArtifactFilter = new ExclusionsDependencyFilter( exclusions ); } record = projectRealmCache.put( extensionRealms, projectRealm, extensionArtifactFilter ); @@ -328,16 +335,17 @@ record = projectRealmCache.put( extensionRealms, projectRealm, extensionArtifact return record; } - private List resolveExtensionArtifacts( Plugin extensionPlugin, RepositoryRequest repositoryRequest, + private List resolveExtensionArtifacts( Plugin extensionPlugin, List repositories, ProjectBuildingRequest request ) throws PluginResolutionException { - ArtifactResolutionRequest artifactRequest = new ArtifactResolutionRequest( repositoryRequest ); - artifactRequest.setServers( request.getServers() ); - artifactRequest.setMirrors( request.getMirrors() ); - artifactRequest.setProxies( request.getProxies() ); + DependencyNode root = + pluginDependenciesResolver.resolve( extensionPlugin, null, null, repositories, + request.getRepositorySession() ); - return pluginDependenciesResolver.resolve( extensionPlugin, null, artifactRequest, null ); + PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); + root.accept( nlg ); + return nlg.getArtifacts( false ); } public void selectProjectRealm( MavenProject project ) diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java index d4f76e0870..0aa8d216e3 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java @@ -25,24 +25,24 @@ import java.util.Properties; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.model.Profile; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.repository.ArtifactTransferListener; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; +import org.sonatype.aether.RepositorySystemSession; public class DefaultProjectBuildingRequest implements ProjectBuildingRequest { + private RepositorySystemSession repositorySession; + private boolean offline; private boolean forceUpdate; - private RepositoryCache repositoryCache; - private ArtifactRepository localRepository; private List remoteRepositories; @@ -126,18 +126,6 @@ public ProjectBuildingRequest setForceUpdate( boolean forceUpdate ) return this; } - public ProjectBuildingRequest setRepositoryCache( RepositoryCache repositoryCache ) - { - this.repositoryCache = repositoryCache; - - return this; - } - - public RepositoryCache getRepositoryCache() - { - return repositoryCache; - } - public ProjectBuildingRequest setLocalRepository( ArtifactRepository localRepository ) { this.localRepository = localRepository; @@ -393,4 +381,15 @@ public void setTransferListener( ArtifactTransferListener transferListener ) this.transferListener = transferListener; } + public RepositorySystemSession getRepositorySession() + { + return repositorySession; + } + + public DefaultProjectBuildingRequest setRepositorySession( RepositorySystemSession repositorySession ) + { + this.repositorySession = repositorySession; + return this; + } + } diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java index ddcd919204..3a3c37f201 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.List; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.model.building.ModelProblem; /** @@ -43,18 +42,17 @@ class DefaultProjectBuildingResult private List problems; - private ArtifactResolutionResult artifactResolutionResult; + private DependencyResolutionResult dependencyResolutionResult; /** * Creates a new result with the specified contents. * * @param project The project that was built, may be {@code null}. * @param problems The problems that were encouterned, may be {@code null}. - * @param dependencyResolutionResult The result of the artifact resolution for the project dependencies, may be - * {@code null}. + * @param dependencyResolutionResult The result of the resolution for the project dependencies, may be {@code null}. */ public DefaultProjectBuildingResult( MavenProject project, List problems, - ArtifactResolutionResult dependencyResolutionResult ) + DependencyResolutionResult dependencyResolutionResult ) { this.projectId = ( project != null ) ? project.getGroupId() + ':' + project.getArtifactId() + ':' + project.getVersion() @@ -62,7 +60,7 @@ public DefaultProjectBuildingResult( MavenProject project, List pr this.pomFile = ( project != null ) ? project.getFile() : null; this.project = project; this.problems = problems; - this.artifactResolutionResult = dependencyResolutionResult; + this.dependencyResolutionResult = dependencyResolutionResult; } /** @@ -104,9 +102,9 @@ public List getProblems() return problems; } - public ArtifactResolutionResult getArtifactResolutionResult() + public DependencyResolutionResult getDependencyResolutionResult() { - return artifactResolutionResult; + return dependencyResolutionResult; } } diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java new file mode 100644 index 0000000000..db7ca64b7f --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java @@ -0,0 +1,232 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.Exclusion; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.logging.Logger; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.ArtifactTypeRegistry; +import org.sonatype.aether.collection.CollectRequest; +import org.sonatype.aether.collection.DependencyCollectionException; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.graph.DependencyVisitor; +import org.sonatype.aether.resolution.ArtifactResolutionException; +import org.sonatype.aether.resolution.ArtifactResult; +import org.sonatype.aether.util.artifact.JavaScopes; + +/** + * @author Benjamin Bentmann + */ +@Component( role = ProjectDependenciesResolver.class ) +public class DefaultProjectDependenciesResolver + implements ProjectDependenciesResolver +{ + + @Requirement + private Logger logger; + + @Requirement + private RepositorySystem repoSystem; + + public DependencyResolutionResult resolve( DependencyResolutionRequest request ) + throws DependencyResolutionException + { + DefaultDependencyResolutionResult result = new DefaultDependencyResolutionResult(); + + MavenProject project = request.getMavenProject(); + RepositorySystemSession session = request.getRepositorySession(); + DependencyFilter filter = request.getResolutionFilter(); + + ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); + + CollectRequest collect = new CollectRequest(); + collect.setRequestContext( "project" ); + collect.setRepositories( project.getRemoteProjectRepositories() ); + + if ( project.getDependencyArtifacts() == null ) + { + for ( Dependency dependency : project.getDependencies() ) + { + collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ) ); + } + } + else + { + Map dependencies = new HashMap(); + for ( Dependency dependency : project.getDependencies() ) + { + String key = dependency.getManagementKey(); + dependencies.put( key, dependency ); + } + for ( Artifact artifact : project.getDependencyArtifacts() ) + { + String key = artifact.getDependencyConflictId(); + Dependency dependency = dependencies.get( key ); + Collection exclusions = dependency != null ? dependency.getExclusions() : null; + org.sonatype.aether.graph.Dependency dep = RepositoryUtils.toDependency( artifact, exclusions ); + if ( !JavaScopes.SYSTEM.equals( dep.getScope() ) && dep.getArtifact().getFile() != null ) + { + // enable re-resolution + dep = dep.setArtifact( dep.getArtifact().setFile( null ) ); + } + collect.addDependency( dep ); + } + } + + DependencyManagement depMngt = project.getDependencyManagement(); + if ( depMngt != null ) + { + for ( Dependency dependency : depMngt.getDependencies() ) + { + collect.addManagedDependency( RepositoryUtils.toDependency( dependency, stereotypes ) ); + } + } + + DependencyNode node; + try + { + node = repoSystem.collectDependencies( session, collect ).getRoot(); + result.setDependencyGraph( node ); + } + catch ( DependencyCollectionException e ) + { + result.setDependencyGraph( e.getResult().getRoot() ); + result.setCollectionErrors( e.getResult().getExceptions() ); + + throw new DependencyResolutionException( result, "Could not resolve dependencies for project " + + project.getId() + ": " + e.getMessage(), e ); + } + + if ( logger.isWarnEnabled() ) + { + for ( DependencyNode child : node.getChildren() ) + { + if ( !child.getRelocations().isEmpty() ) + { + logger.warn( "The artifact " + child.getRelocations().get( 0 ) + " has been relocated to " + + child.getDependency().getArtifact() ); + } + } + } + + if ( logger.isDebugEnabled() ) + { + node.accept( new GraphLogger( project ) ); + } + + try + { + process( result, repoSystem.resolveDependencies( session, node, filter ) ); + } + catch ( ArtifactResolutionException e ) + { + process( result, e.getResults() ); + + throw new DependencyResolutionException( result, "Could not resolve dependencies for project " + + project.getId() + ": " + e.getMessage(), e ); + } + + return result; + } + + private void process( DefaultDependencyResolutionResult result, Collection results ) + { + for ( ArtifactResult ar : results ) + { + if ( ar.isResolved() ) + { + result.addResolvedDependency( ar.getRequest().getDependencyNode().getDependency() ); + } + else + { + result.setResolutionErrors( ar.getRequest().getDependencyNode().getDependency(), ar.getExceptions() ); + } + } + } + + class GraphLogger + implements DependencyVisitor + { + + private final MavenProject project; + + private String indent = ""; + + public GraphLogger( MavenProject project ) + { + this.project = project; + } + + public boolean visitEnter( DependencyNode node ) + { + StringBuilder buffer = new StringBuilder( 128 ); + buffer.append( indent ); + org.sonatype.aether.graph.Dependency dep = node.getDependency(); + if ( dep != null ) + { + org.sonatype.aether.artifact.Artifact art = dep.getArtifact(); + + buffer.append( art ); + buffer.append( ':' ).append( dep.getScope() ); + + if ( node.getPremanagedScope() != null && !node.getPremanagedScope().equals( dep.getScope() ) ) + { + buffer.append( " (scope managed from " ).append( node.getPremanagedScope() ).append( ")" ); + } + + if ( node.getPremanagedVersion() != null && !node.getPremanagedVersion().equals( art.getVersion() ) ) + { + buffer.append( " (version managed from " ).append( node.getPremanagedVersion() ).append( ")" ); + } + } + else + { + buffer.append( project.getGroupId() ); + buffer.append( ':' ).append( project.getArtifactId() ); + buffer.append( ':' ).append( project.getPackaging() ); + buffer.append( ':' ).append( project.getVersion() ); + } + + logger.debug( buffer.toString() ); + indent += " "; + return true; + } + + public boolean visitLeave( DependencyNode node ) + { + indent = indent.substring( 0, indent.length() - 3 ); + return true; + } + + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java index 271e7f76ab..d895fdf0a7 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java @@ -24,9 +24,9 @@ import java.util.List; import java.util.Map; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.graph.DependencyFilter; /** * Default project realm cache implementation. Assumes cached data does not change. @@ -84,7 +84,7 @@ public CacheRecord get( List extensionRealms ) } public CacheRecord put( List extensionRealms, ClassRealm projectRealm, - ArtifactFilter extensionArtifactFilter ) + DependencyFilter extensionArtifactFilter ) { if ( projectRealm == null ) { diff --git a/maven-core/src/main/java/org/apache/maven/execution/SessionRepositoryCache.java b/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionException.java similarity index 56% rename from maven-core/src/main/java/org/apache/maven/execution/SessionRepositoryCache.java rename to maven-core/src/main/java/org/apache/maven/project/DependencyResolutionException.java index e70d8322b3..50e601e7e9 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/SessionRepositoryCache.java +++ b/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionException.java @@ -1,4 +1,4 @@ -package org.apache.maven.execution; +package org.apache.maven.project; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,31 +19,24 @@ * under the License. */ -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.maven.artifact.repository.RepositoryCache; -import org.apache.maven.artifact.repository.RepositoryRequest; - /** - * Provides a simple repository cache whose lifetime is scoped to a single Maven session. - * * @author Benjamin Bentmann */ -class SessionRepositoryCache - implements RepositoryCache +public class DependencyResolutionException + extends Exception { - private Map cache = new ConcurrentHashMap( 256 ); + private DependencyResolutionResult result; - public Object get( RepositoryRequest request, Object key ) + public DependencyResolutionException( DependencyResolutionResult result, String message, Throwable cause ) { - return cache.get( key ); + super( message, cause ); + this.result = result; } - public void put( RepositoryRequest request, Object key, Object data ) + public DependencyResolutionResult getResult() { - cache.put( key, data ); + return result; } } diff --git a/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java b/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java new file mode 100644 index 0000000000..67ce722e6f --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java @@ -0,0 +1,79 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.graph.DependencyFilter; + +/** + * A request to resolve the dependencies of a project. + * + * @author Benjamin Bentmann + */ +public interface DependencyResolutionRequest +{ + + /** + * Gets the project to resolve dependencies for. + * + * @return The project to resolve dependencies for or {@code null} if not set. + */ + MavenProject getMavenProject(); + + /** + * Sets the project to resolve dependencies for. + * + * @param project The project to resolve dependencies for, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + DependencyResolutionRequest setMavenProject( MavenProject project ); + + /** + * Gets the filter used to exclude some dependencies from resolution. + * + * @return The filter to exclude dependencies from resolution or {@code null} to resolve all dependencies. + */ + DependencyFilter getResolutionFilter(); + + /** + * Sets the filter used to exclude some dependencies from resolution. + * + * @param filter The filter to exclude dependencies from resolution, may be {@code null} to resolve all + * dependencies. + * @return This request for chaining, never {@code null}. + */ + DependencyResolutionRequest setResolutionFilter( DependencyFilter filter ); + + /** + * Gets the session to use for repository access. + * + * @return The repository session or {@code null} if not set. + */ + RepositorySystemSession getRepositorySession(); + + /** + * Sets the session to use for repository access. + * + * @param repositorySession The repository session to use. + * @return This request for chaining, never {@code null}. + */ + DependencyResolutionRequest setRepositorySession( RepositorySystemSession repositorySession ); + +} diff --git a/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java b/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java new file mode 100644 index 0000000000..81ae084578 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java @@ -0,0 +1,79 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.util.List; + +import org.sonatype.aether.graph.Dependency; +import org.sonatype.aether.graph.DependencyNode; + +/** + * The result of a project dependency resolution. + * + * @author Benjamin Bentmann + */ +public interface DependencyResolutionResult +{ + + /** + * Gets the dependency graph of the project. + * + * @return The dependency graph or {@code null} if not available. + */ + DependencyNode getDependencyGraph(); + + /** + * Gets the transitive dependencies of the project that were not excluded by a filter, whether successfully resolved + * or not. + * + * @return The transitive dependencies, never {@code null}. + */ + List getDependencies(); + + /** + * Gets the dependencies that were successfully resolved. + * + * @return The resolved dependencies, never {@code null}. + */ + List getResolvedDependencies(); + + /** + * Gets the dependencies that could not be resolved. + * + * @return The unresolved dependencies, never {@code null}. + */ + List getUnresolvedDependencies(); + + /** + * Gets the errors that occurred while building the dependency graph. + * + * @return The errors that occurred while building the dependency graph, never {@code null}. + */ + List getCollectionErrors(); + + /** + * Gets the errors that occurred while resolving the specified dependency. + * + * @param dependency The dependency for which to retrieve the errors, must not be {@code null}. + * @return The resolution errors for the specified dependency, never {@code null}. + */ + List getResolutionErrors( Dependency dependency ); + +} diff --git a/maven-core/src/main/java/org/apache/maven/project/MavenProject.java b/maven-core/src/main/java/org/apache/maven/project/MavenProject.java index 03d60184bb..f36aefdefc 100644 --- a/maven-core/src/main/java/org/apache/maven/project/MavenProject.java +++ b/maven-core/src/main/java/org/apache/maven/project/MavenProject.java @@ -1,22 +1,18 @@ package org.apache.maven.project; /* - * 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. + * 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. */ import java.io.File; @@ -35,6 +31,7 @@ import java.util.Properties; import java.util.Set; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.DependencyResolutionRequiredException; @@ -75,6 +72,8 @@ import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.repository.RemoteRepository; /** * The concern of the project is provide runtime values based on the model. @@ -119,6 +118,10 @@ public class MavenProject private List pluginArtifactRepositories; + private List remoteProjectRepositories; + + private List remotePluginRepositories; + private List attachedArtifacts; private MavenProject executionProject; @@ -171,14 +174,14 @@ public class MavenProject private ProjectBuildingRequest projectBuilderConfiguration; private RepositorySystem repositorySystem; - + private File parentFile; private Map context; private ClassRealm classRealm; - private ArtifactFilter extensionArtifactFilter; + private DependencyFilter extensionDependencyFilter; private final Set lifecyclePhases = Collections.synchronizedSet( new LinkedHashSet() ); @@ -208,10 +211,10 @@ public MavenProject( MavenProject project ) { deepCopy( project ); } - + @Deprecated public MavenProject( Model model, RepositorySystem repositorySystem ) - { + { this.repositorySystem = repositorySystem; setModel( model ); } @@ -228,7 +231,7 @@ public void setParentFile( File parentFile ) /** * Constructor - * + * * @param repositorySystem - may not be null * @param mavenProjectBuilder * @param projectBuilderConfiguration @@ -377,7 +380,7 @@ public void setParent( MavenProject parent ) { this.parent = parent; } - + public boolean hasParent() { return getParent() != null; @@ -498,12 +501,11 @@ public List getCompileClasspathElements() list.add( getBuild().getOutputDirectory() ); for ( Artifact a : getArtifacts() ) - { + { if ( a.getArtifactHandler().isAddedToClasspath() ) { // TODO: let the scope handler deal with this - if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) - || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) + if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) { addArtifactPath( a, list ); } @@ -524,8 +526,7 @@ public List getCompileArtifacts() if ( a.getArtifactHandler().isAddedToClasspath() ) { // TODO: let the scope handler deal with this - if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) - || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) + if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) { list.add( a ); } @@ -549,8 +550,7 @@ public List getCompileDependencies() for ( Artifact a : getArtifacts() ) { // TODO: let the scope handler deal with this - if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) - || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) + if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) { Dependency dependency = new Dependency(); @@ -577,11 +577,11 @@ public List getTestClasspathElements() list.add( getBuild().getTestOutputDirectory() ); list.add( getBuild().getOutputDirectory() ); - + for ( Artifact a : getArtifacts() ) - { + { if ( a.getArtifactHandler().isAddedToClasspath() ) - { + { addArtifactPath( a, list ); } } @@ -1069,7 +1069,7 @@ public void setArtifacts( Set artifacts ) * All dependencies that this project has, including transitive ones. Contents are lazily * populated, so depending on what phases have run dependencies in some scopes won't be * included. eg. if only compile phase has run, dependencies with scope test won't be included. - * + * * @return {@link Set} < {@link Artifact} > * @see #getDependencyArtifacts() to get only direct dependencies */ @@ -1243,8 +1243,7 @@ public Set getExtensionArtifacts() version = ext.getVersion(); } - Artifact artifact = - repositorySystem.createArtifact( ext.getGroupId(), ext.getArtifactId(), version, null, "jar" ); + Artifact artifact = repositorySystem.createArtifact( ext.getGroupId(), ext.getArtifactId(), version, null, "jar" ); if ( artifact != null ) { @@ -1345,6 +1344,7 @@ private Build getModelBuild() public void setRemoteArtifactRepositories( List remoteArtifactRepositories ) { this.remoteArtifactRepositories = remoteArtifactRepositories; + this.remoteProjectRepositories = RepositoryUtils.toRepos( getRemoteArtifactRepositories() ); } public List getRemoteArtifactRepositories() @@ -1360,6 +1360,7 @@ public List getRemoteArtifactRepositories() public void setPluginArtifactRepositories( List pluginArtifactRepositories ) { this.pluginArtifactRepositories = pluginArtifactRepositories; + this.remotePluginRepositories = RepositoryUtils.toRepos( getPluginArtifactRepositories() ); } /** @@ -1378,8 +1379,7 @@ public List getPluginArtifactRepositories() public ArtifactRepository getDistributionManagementArtifactRepository() { - return getArtifact().isSnapshot() && ( getSnapshotArtifactRepository() != null ) ? getSnapshotArtifactRepository() - : getReleaseArtifactRepository(); + return getArtifact().isSnapshot() && ( getSnapshotArtifactRepository() != null ) ? getSnapshotArtifactRepository() : getReleaseArtifactRepository(); } public List getPluginRepositories() @@ -1387,6 +1387,16 @@ public List getPluginRepositories() return getModel().getRepositories(); } + public List getRemoteProjectRepositories() + { + return remoteProjectRepositories; + } + + public List getRemotePluginRepositories() + { + return remotePluginRepositories; + } + public void setActiveProfiles( List activeProfiles ) { this.activeProfiles.addAll( activeProfiles ); @@ -1415,7 +1425,7 @@ public void setInjectedProfileIds( String source, List injectedProfileId * settings.xml}. The profile identifiers are grouped by the identifier of their source, e.g. {@code * ::} for a POM profile or {@code external} for profiles from the {@code * settings.xml}. - * + * * @return The identifiers of all injected profiles, indexed by the source from which the profiles originated, never * {@code null}. */ @@ -1557,7 +1567,7 @@ public void setCollectedProjects( List collectedProjects ) /** * Direct dependencies that this project has. - * + * * @return {@link Set} < {@link Artifact} > * @see #getArtifacts() to get all transitive dependencies */ @@ -1609,8 +1619,7 @@ public Map getManagedVersionMap() List deps; DependencyManagement dependencyManagement = getDependencyManagement(); - if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null ) - && ( deps.size() > 0 ) ) + if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null ) && ( deps.size() > 0 ) ) { map = new HashMap(); for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); ) @@ -1685,8 +1694,7 @@ public List getBuildExtensions() public void addProjectReference( MavenProject project ) { - projectReferences.put( getProjectReferenceId( project.getGroupId(), project.getArtifactId(), - project.getVersion() ), project ); + projectReferences.put( getProjectReferenceId( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project ); } /** @@ -1844,7 +1852,7 @@ protected ArtifactRepository getReleaseArtifactRepository() { } } - + return releaseArtifactRepository; } @@ -1864,7 +1872,7 @@ protected ArtifactRepository getSnapshotArtifactRepository() { } } - + return snapshotArtifactRepository; } @@ -1992,9 +2000,9 @@ private static String getProjectReferenceId( String groupId, String artifactId, * Sets the value of the context value of this project identified * by the given key. If the supplied value is null, * the context value is removed from this project. - * + * * Context values are intended to allow core extensions to associate - * derived state with project instances. + * derived state with project instances. */ public void setContextValue( String key, Object value ) { @@ -2013,8 +2021,8 @@ public void setContextValue( String key, Object value ) } /** - * Returns context value of this project associated with the given key - * or null if this project has no such value. + * Returns context value of this project associated with the given key + * or null if this project has no such value. */ public Object getContextValue( String key ) { @@ -2029,7 +2037,7 @@ public Object getContextValue( String key ) * Sets the project's class realm. Warning: This is an internal utility method that is only public * for technical reasons, it is not part of the public API. In particular, this method can be changed or deleted * without prior notice and must not be used by plugins. - * + * * @param classRealm The class realm hosting the build extensions of this project, may be {@code null}. */ public void setClassRealm( ClassRealm classRealm ) @@ -2042,7 +2050,7 @@ public void setClassRealm( ClassRealm classRealm ) * Warning: This is an internal utility method that is only public for technical reasons, it is not * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be * used by plugins. - * + * * @return The project's class realm or {@code null}. */ public ClassRealm getClassRealm() @@ -2054,24 +2062,25 @@ public ClassRealm getClassRealm() * Sets the artifact filter used to exclude shared extension artifacts from plugin realms. Warning: * This is an internal utility method that is only public for technical reasons, it is not part of the public API. * In particular, this method can be changed or deleted without prior notice and must not be used by plugins. - * - * @param extensionArtifactFilter The artifact filter to apply to plugins, may be {@code null}. + * + * @param extensionDependencyFilter The dependency filter to apply to plugins, may be {@code null}. */ - public void setExtensionArtifactFilter( ArtifactFilter extensionArtifactFilter ) + public void setExtensionDependencyFilter( DependencyFilter extensionDependencyFilter ) { - this.extensionArtifactFilter = extensionArtifactFilter; + this.extensionDependencyFilter = extensionDependencyFilter; } /** - * Gets the artifact filter used to exclude shared extension artifacts from plugin realms. Warning: - * This is an internal utility method that is only public for technical reasons, it is not part of the public API. - * In particular, this method can be changed or deleted without prior notice and must not be used by plugins. - * - * @return The artifact filter or {@code null}. + * Gets the dependency filter used to exclude shared extension artifacts from plugin realms. + * Warning: This is an internal utility method that is only public for technical reasons, it is not + * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be + * used by plugins. + * + * @return The dependency filter or {@code null}. */ - public ArtifactFilter getExtensionArtifactFilter() + public DependencyFilter getExtensionDependencyFilter() { - return extensionArtifactFilter; + return extensionDependencyFilter; } /** @@ -2079,7 +2088,7 @@ public ArtifactFilter getExtensionArtifactFilter() * Warning: This is an internal utility method that is only public for technical reasons, it is not * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be * used by plugins. - * + * * @param artifacts The set of artifacts, may be {@code null}. */ public void setResolvedArtifacts( Set artifacts ) @@ -2094,7 +2103,7 @@ public void setResolvedArtifacts( Set artifacts ) * Warning: This is an internal utility method that is only public for technical reasons, it is not * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be * used by plugins. - * + * * @param artifactFilter The artifact filter, may be {@code null} to exclude all artifacts. */ public void setArtifactFilter( ArtifactFilter artifactFilter ) @@ -2120,7 +2129,7 @@ public boolean hasCompletedPhase( String phase ) * Warning: This is an internal utility method that is only public for technical reasons, it is not * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be * used by plugins. - * + * * @param lifecyclePhase The lifecycle phase to add, must not be {@code null}. */ public void addLifecyclePhase( String lifecyclePhase ) diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java index f43fbd1cb6..b902fa5479 100644 --- a/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java +++ b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java @@ -24,12 +24,12 @@ import java.util.Properties; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.model.Profile; -import org.apache.maven.repository.ArtifactTransferListener; +import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; +import org.sonatype.aether.RepositorySystemSession; public interface ProjectBuildingRequest { @@ -42,12 +42,8 @@ public interface ProjectBuildingRequest boolean isForceUpdate(); - ProjectBuildingRequest setRepositoryCache( RepositoryCache repositoryCache ); - - RepositoryCache getRepositoryCache(); - ProjectBuildingRequest setLocalRepository( ArtifactRepository localRepository ); - + ArtifactRepository getLocalRepository(); ProjectBuildingRequest setRemoteRepositories( List remoteRepositories ); @@ -73,7 +69,7 @@ public interface ProjectBuildingRequest /** * Sets the system properties to use for interpolation and profile activation. The system properties are collected * from the runtime environment like {@link System#getProperties()} and environment variables. - * + * * @param systemProperties The system properties, may be {@code null}. * @return This request, never {@code null}. */ @@ -82,7 +78,7 @@ public interface ProjectBuildingRequest /** * Gets the system properties to use for interpolation and profile activation. The system properties are collected * from the runtime environment like {@link System#getProperties()} and environment variables. - * + * * @return The system properties, never {@code null}. */ Properties getSystemProperties(); @@ -91,7 +87,7 @@ public interface ProjectBuildingRequest * Sets the user properties to use for interpolation and profile activation. The user properties have been * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command * line. - * + * * @param userProperties The user properties, may be {@code null}. * @return This request, never {@code null}. */ @@ -101,12 +97,12 @@ public interface ProjectBuildingRequest * Gets the user properties to use for interpolation and profile activation. The user properties have been * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command * line. - * + * * @return The user properties, never {@code null}. */ Properties getUserProperties(); - void setProject( MavenProject mavenProject ); + void setProject(MavenProject mavenProject); MavenProject getProject(); @@ -120,7 +116,7 @@ public interface ProjectBuildingRequest /** * Controls the level of validation to perform on processed models. By default, models are validated in strict mode. - * + * * @param validationLevel The level of validation to perform on processed models, e.g. * {@link ModelBuildingRequest#VALIDATION_LEVEL_STRICT}. * @return This configuration, never {@code null}. @@ -129,53 +125,53 @@ public interface ProjectBuildingRequest /** * Gets the level of validation to perform on processed models. - * + * * @return The level of validation to perform on processed models. */ int getValidationLevel(); // Profiles - + /** * Set any active profiles that the {@link ProjectBuilder} should consider while constructing * a {@link MavenProject}. */ void setActiveProfileIds( List activeProfileIds ); - + List getActiveProfileIds(); void setInactiveProfileIds( List inactiveProfileIds ); List getInactiveProfileIds(); - + /** - * Add a {@link org.apache.maven.model.Profile} that has come from an external source. This may be from a custom - * configuration like the MavenCLI settings.xml file, or from a custom dialog in an IDE integration like M2Eclipse. + * Add a {@link org.apache.maven.model.Profile} that has come from an external source. This may be from a custom configuration + * like the MavenCLI settings.xml file, or from a custom dialog in an IDE integration like M2Eclipse. * @param profile */ void addProfile( Profile profile ); - + void setProfiles( List profiles ); - + List getProfiles(); /** * Gets the start time of the build. - * + * * @return The start time of the build or {@code null} if unknown. */ Date getBuildStartTime(); /** * Sets the start time of the build. - * + * * @param buildStartTime The start time of the build, may be {@code null}. * @return This request, never {@code null}. */ void setBuildStartTime( Date buildStartTime ); - ArtifactTransferListener getTransferListener(); + RepositorySystemSession getRepositorySession(); - void setTransferListener( ArtifactTransferListener transferListener ); + ProjectBuildingRequest setRepositorySession( RepositorySystemSession repositorySession ); } diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java index 4128c69147..bf9d265f71 100644 --- a/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java +++ b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java @@ -22,7 +22,6 @@ import java.io.File; import java.util.List; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.model.building.ModelProblem; /** @@ -70,6 +69,6 @@ public interface ProjectBuildingResult * @return The result of the dependency resolution for the project or {@code null} if the project dependencies were * not requested. */ - ArtifactResolutionResult getArtifactResolutionResult(); + DependencyResolutionResult getDependencyResolutionResult(); } diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java new file mode 100644 index 0000000000..36572c2fc3 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java @@ -0,0 +1,40 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +/** + * Resolves the transitive dependencies of a project. + * + * @author Benjamin Bentmann + */ +public interface ProjectDependenciesResolver +{ + + /** + * Resolves the transitive dependencies of a project. + * + * @param request The resolution request holding the parameters, must not be {@code null}. + * @return The resolution result, never {@code null}. + * @throws DependencyResolutionException If any project dependency could not be resolved. + */ + DependencyResolutionResult resolve( DependencyResolutionRequest request ) + throws DependencyResolutionException; + +} diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java b/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java index 4ae0f3c1f5..e36d1d255a 100644 --- a/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java @@ -21,8 +21,8 @@ import java.util.List; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.sonatype.aether.graph.DependencyFilter; /** * Caches project class realms. Warning: This is an internal utility interface that is only public for @@ -40,9 +40,9 @@ public static class CacheRecord public final ClassRealm realm; - public final ArtifactFilter extensionArtifactFilter; + public final DependencyFilter extensionArtifactFilter; - public CacheRecord( ClassRealm realm, ArtifactFilter extensionArtifactFilter ) + public CacheRecord( ClassRealm realm, DependencyFilter extensionArtifactFilter ) { this.realm = realm; this.extensionArtifactFilter = extensionArtifactFilter; @@ -53,7 +53,7 @@ public CacheRecord( ClassRealm realm, ArtifactFilter extensionArtifactFilter ) CacheRecord get( List extensionRealms ); CacheRecord put( List extensionRealms, ClassRealm projectRealm, - ArtifactFilter extensionArtifactFilter ); + DependencyFilter extensionArtifactFilter ); void flush(); diff --git a/maven-core/src/main/java/org/apache/maven/project/ReactorModelResolver.java b/maven-core/src/main/java/org/apache/maven/project/ReactorModelResolver.java new file mode 100644 index 0000000000..414d2b7810 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/project/ReactorModelResolver.java @@ -0,0 +1,182 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.maven.model.Repository; +import org.apache.maven.model.building.FileModelSource; +import org.apache.maven.model.building.ModelSource; +import org.apache.maven.model.resolution.InvalidRepositoryException; +import org.apache.maven.model.resolution.ModelResolver; +import org.apache.maven.model.resolution.UnresolvableModelException; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.impl.ArtifactResolver; +import org.sonatype.aether.impl.RemoteRepositoryManager; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.repository.RepositoryPolicy; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.ArtifactResolutionException; +import org.sonatype.aether.util.artifact.DefaultArtifact; + +/** + * A model resolver to assist building of projects. This resolver gives priority to those repositories that have been + * declared in the POM. + * + * @author Benjamin Bentmann + */ +class ReactorModelResolver + implements ModelResolver +{ + + private final RepositorySystemSession session; + + private final String context = "project"; + + private List repositories; + + private List pomRepositories; + + private final List defaultRepositories; + + private final ArtifactResolver resolver; + + private final RemoteRepositoryManager remoteRepositoryManager; + + private final Set repositoryIds; + + private final ReactorModelPool modelPool; + + public ReactorModelResolver( RepositorySystemSession session, ArtifactResolver resolver, + RemoteRepositoryManager remoteRepositoryManager, List repositories, + ReactorModelPool modelPool ) + { + this.session = session; + this.resolver = resolver; + this.remoteRepositoryManager = remoteRepositoryManager; + this.pomRepositories = new ArrayList(); + this.defaultRepositories = repositories; + this.repositories = repositories; + this.repositoryIds = new HashSet(); + this.modelPool = modelPool; + } + + private ReactorModelResolver( ReactorModelResolver original ) + { + this.session = original.session; + this.resolver = original.resolver; + this.remoteRepositoryManager = original.remoteRepositoryManager; + this.pomRepositories = original.pomRepositories; + this.defaultRepositories = original.defaultRepositories; + this.repositories = original.repositories; + this.repositoryIds = new HashSet( original.repositoryIds ); + this.modelPool = original.modelPool; + } + + public void addRepository( Repository repository ) + throws InvalidRepositoryException + { + if ( !repositoryIds.add( repository.getId() ) ) + { + return; + } + + List newRepositories = Collections.singletonList( convert( repository ) ); + + pomRepositories = + remoteRepositoryManager.aggregateRepositories( session, pomRepositories, newRepositories, true ); + repositories = + remoteRepositoryManager.aggregateRepositories( session, pomRepositories, defaultRepositories, false ); + } + + private static RemoteRepository convert( Repository repository ) + { + RemoteRepository result = + new RemoteRepository( repository.getId(), repository.getLayout(), repository.getUrl() ); + result.setPolicy( true, convert( repository.getSnapshots() ) ); + result.setPolicy( false, convert( repository.getReleases() ) ); + return result; + } + + private static RepositoryPolicy convert( org.apache.maven.model.RepositoryPolicy policy ) + { + boolean enabled = true; + String checksums = RepositoryPolicy.CHECKSUM_POLICY_WARN; + String updates = RepositoryPolicy.UPDATE_POLICY_DAILY; + + if ( policy != null ) + { + enabled = policy.isEnabled(); + if ( policy.getUpdatePolicy() != null ) + { + updates = policy.getUpdatePolicy(); + } + if ( policy.getChecksumPolicy() != null ) + { + checksums = policy.getChecksumPolicy(); + } + } + + return new RepositoryPolicy( enabled, updates, checksums ); + } + + public ModelResolver newCopy() + { + return new ReactorModelResolver( this ); + } + + public ModelSource resolveModel( String groupId, String artifactId, String version ) + throws UnresolvableModelException + { + File pomFile = null; + + if ( modelPool != null ) + { + pomFile = modelPool.get( groupId, artifactId, version ); + } + + if ( pomFile == null ) + { + Artifact pomArtifact = new DefaultArtifact( groupId, artifactId, "", "pom", version ); + + try + { + ArtifactRequest request = new ArtifactRequest( pomArtifact, repositories, context ); + pomArtifact = resolver.resolveArtifact( session, request ).getArtifact(); + } + catch ( ArtifactResolutionException e ) + { + throw new UnresolvableModelException( "Failed to resolve POM for " + groupId + ":" + artifactId + ":" + + version + " due to " + e.getMessage(), groupId, artifactId, version, e ); + } + + pomFile = pomArtifact.getFile(); + } + + return new FileModelSource( pomFile ); + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java b/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java deleted file mode 100644 index 86a6f58ad0..0000000000 --- a/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java +++ /dev/null @@ -1,189 +0,0 @@ -package org.apache.maven.project; - -/* - * 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. - */ - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; -import org.apache.maven.artifact.resolver.ResolutionErrorHandler; -import org.apache.maven.model.Repository; -import org.apache.maven.model.building.FileModelSource; -import org.apache.maven.model.building.ModelSource; -import org.apache.maven.model.resolution.InvalidRepositoryException; -import org.apache.maven.model.resolution.ModelResolver; -import org.apache.maven.model.resolution.UnresolvableModelException; -import org.apache.maven.repository.RepositorySystem; - -/** - * Implements a model resolver backed by the Maven Repository API and the reactor. - * - * @author Benjamin Bentmann - */ -class RepositoryModelResolver - implements ModelResolver -{ - - private RepositorySystem repositorySystem; - - private ResolutionErrorHandler resolutionErrorHandler; - - private ProjectBuildingRequest projectBuildingRequest; - - private List pomRepositories; - - private List remoteRepositories; - - private ReactorModelPool reactorModelPool; - - private Set repositoryIds; - - public RepositoryModelResolver( RepositorySystem repositorySystem, ResolutionErrorHandler resolutionErrorHandler, - ProjectBuildingRequest projectBuildingRequest, ReactorModelPool reactorModelPool ) - { - if ( repositorySystem == null ) - { - throw new IllegalArgumentException( "no repository system specified" ); - } - this.repositorySystem = repositorySystem; - - if ( resolutionErrorHandler == null ) - { - throw new IllegalArgumentException( "no resolution error handler specified" ); - } - this.resolutionErrorHandler = resolutionErrorHandler; - - if ( projectBuildingRequest == null ) - { - throw new IllegalArgumentException( "no project building request specified" ); - } - this.projectBuildingRequest = projectBuildingRequest; - - this.remoteRepositories = new ArrayList(); - if ( projectBuildingRequest.getRemoteRepositories() != null ) - { - this.remoteRepositories.addAll( projectBuildingRequest.getRemoteRepositories() ); - } - - this.pomRepositories = new ArrayList(); - - this.repositoryIds = new HashSet(); - - this.reactorModelPool = reactorModelPool; - } - - private RepositoryModelResolver( RepositoryModelResolver original ) - { - this.repositorySystem = original.repositorySystem; - this.resolutionErrorHandler = original.resolutionErrorHandler; - this.projectBuildingRequest = original.projectBuildingRequest; - this.reactorModelPool = original.reactorModelPool; - this.remoteRepositories = new ArrayList( original.remoteRepositories ); - this.repositoryIds = new HashSet( original.repositoryIds ); - this.pomRepositories = new ArrayList( original.pomRepositories ); - } - - public ModelResolver newCopy() - { - return new RepositoryModelResolver( this ); - } - - public void addRepository( Repository repository ) - throws InvalidRepositoryException - { - if ( !repositoryIds.add( repository.getId() ) ) - { - return; - } - - try - { - ArtifactRepository repo = repositorySystem.buildArtifactRepository( repository ); - - repositorySystem.injectMirror( Arrays.asList( repo ), projectBuildingRequest.getMirrors() ); - - repositorySystem.injectProxy( Arrays.asList( repo ), projectBuildingRequest.getProxies() ); - - repositorySystem.injectAuthentication( Arrays.asList( repo ), projectBuildingRequest.getServers() ); - - pomRepositories.add( repo ); - - remoteRepositories = new ArrayList(); - remoteRepositories.addAll( pomRepositories ); - remoteRepositories.addAll( projectBuildingRequest.getRemoteRepositories() ); - - remoteRepositories = repositorySystem.getEffectiveRepositories( remoteRepositories ); - } - catch ( Exception e ) - { - throw new InvalidRepositoryException( e.getMessage(), repository, e ); - } - } - - public ModelSource resolveModel( String groupId, String artifactId, String version ) - throws UnresolvableModelException - { - File pomFile = null; - - if ( reactorModelPool != null ) - { - pomFile = reactorModelPool.get( groupId, artifactId, version ); - } - - if ( pomFile == null ) - { - Artifact artifactParent = repositorySystem.createProjectArtifact( groupId, artifactId, version ); - - ArtifactResolutionRequest request = new ArtifactResolutionRequest(); - request.setArtifact( artifactParent ); - request.setRemoteRepositories( remoteRepositories ); - request.setLocalRepository( projectBuildingRequest.getLocalRepository() ); - request.setOffline( projectBuildingRequest.isOffline() ); - request.setCache( projectBuildingRequest.getRepositoryCache() ); - request.setTransferListener( projectBuildingRequest.getTransferListener() ); - request.setForceUpdate( projectBuildingRequest.isForceUpdate() ); - - ArtifactResolutionResult result = repositorySystem.resolve( request ); - - try - { - resolutionErrorHandler.throwErrors( request, result ); - } - catch ( ArtifactResolutionException e ) - { - throw new UnresolvableModelException( "Failed to resolve POM for " + groupId + ":" + artifactId + ":" - + version + " due to " + e.getMessage(), groupId, artifactId, version, e ); - } - - pomFile = artifactParent.getFile(); - } - - return new FileModelSource( pomFile ); - } - -} diff --git a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java index d1a666f29b..8908b4f7cf 100644 --- a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java +++ b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java @@ -76,6 +76,7 @@ import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.Logger; +import org.sonatype.aether.transfer.ArtifactNotFoundException; /** * @author Jason van Zyl @@ -116,7 +117,6 @@ private void injectSession( MetadataResolutionRequest request ) request.setServers( session.getRequest().getServers() ); request.setMirrors( session.getRequest().getMirrors() ); request.setProxies( session.getRequest().getProxies() ); - request.setTransferListener( session.getRequest().getTransferListener() ); } } @@ -569,7 +569,6 @@ private ProjectRelocation retrieveRelocatedProject( Artifact artifact, MetadataR try { ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); - configuration.setRepositoryCache( repositoryRequest.getCache() ); configuration.setLocalRepository( repositoryRequest.getLocalRepository() ); configuration.setRemoteRepositories( repositoryRequest.getRemoteRepositories() ); configuration.setOffline( repositoryRequest.isOffline() ); @@ -577,10 +576,10 @@ private ProjectRelocation retrieveRelocatedProject( Artifact artifact, MetadataR configuration.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL ); configuration.setProcessPlugins( false ); configuration.setSystemProperties( getSystemProperties() ); - configuration.setTransferListener( repositoryRequest.getTransferListener() ); configuration.setServers( repositoryRequest.getServers() ); configuration.setMirrors( repositoryRequest.getMirrors() ); configuration.setProxies( repositoryRequest.getProxies() ); + configuration.setRepositorySession( legacySupport.getRepositorySession() ); project = getProjectBuilder().build( pomArtifact, configuration ).getProject(); } @@ -597,11 +596,11 @@ private ProjectRelocation retrieveRelocatedProject( Artifact artifact, MetadataR String message; - if ( e.getCause() instanceof MultipleArtifactsNotFoundException ) + if ( isMissingPom( e ) ) { message = "Missing POM for " + artifact.getId(); } - else if ( e.getCause() instanceof ArtifactResolutionException ) + else if ( isNonTransferrablePom( e ) ) { throw new ArtifactMetadataRetrievalException( "Failed to retrieve POM for " + artifact.getId() + ": " + e.getCause().getMessage(), e.getCause(), @@ -735,6 +734,34 @@ private ModelProblem hasMissingParentPom( ProjectBuildingException e ) return null; } + private boolean isMissingPom( Exception e ) + { + if ( e.getCause() instanceof MultipleArtifactsNotFoundException ) + { + return true; + } + if ( e.getCause() instanceof org.sonatype.aether.resolution.ArtifactResolutionException + && e.getCause().getCause() instanceof ArtifactNotFoundException ) + { + return true; + } + return false; + } + + private boolean isNonTransferrablePom( Exception e ) + { + if ( e.getCause() instanceof ArtifactResolutionException ) + { + return true; + } + if ( e.getCause() instanceof org.sonatype.aether.resolution.ArtifactResolutionException + && !( e.getCause().getCause() instanceof ArtifactNotFoundException ) ) + { + return true; + } + return false; + } + private Properties getSystemProperties() { Properties props = new Properties(); diff --git a/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java b/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java index 1b29261c39..404eb704c4 100644 --- a/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java +++ b/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java @@ -51,6 +51,11 @@ public ProjectArtifactMetadata( Artifact artifact, File file ) this.file = file; } + public File getFile() + { + return file; + } + public String getRemoteFilename() { return getFilename(); diff --git a/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java b/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java index f7c0de5ca6..1bc5193b67 100644 --- a/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java +++ b/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java @@ -125,7 +125,7 @@ public String pathOf( Artifact artifact ) @Override public String getBasedir() { - return userLocalArtifactRepository.getBasedir(); + return ( userLocalArtifactRepository != null ) ? userLocalArtifactRepository.getBasedir() : null; } @Override diff --git a/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java b/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java index 3671948187..fc53103b25 100644 --- a/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java @@ -25,10 +25,8 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.DefaultRepositoryRequest; -import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.repository.ArtifactTransferListener; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; @@ -120,18 +118,6 @@ public DefaultMetadataResolutionRequest setResolveManagedVersions( boolean resol return this; } - public RepositoryCache getCache() - { - return repositoryRequest.getCache(); - } - - public DefaultMetadataResolutionRequest setCache( RepositoryCache cache ) - { - repositoryRequest.setCache( cache ); - - return this; - } - public boolean isOffline() { return repositoryRequest.isOffline(); @@ -156,18 +142,6 @@ public DefaultMetadataResolutionRequest setForceUpdate( boolean forceUpdate ) return this; } - public ArtifactTransferListener getTransferListener() - { - return repositoryRequest.getTransferListener(); - } - - public DefaultMetadataResolutionRequest setTransferListener( ArtifactTransferListener transferListener ) - { - repositoryRequest.setTransferListener( transferListener ); - - return this; - } - public MetadataResolutionRequest setServers( List servers ) { this.servers = servers; diff --git a/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java b/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java index ba0f1c41ac..ea5a2013c0 100644 --- a/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java @@ -23,7 +23,6 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.RepositoryCache; import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; @@ -98,21 +97,6 @@ public interface MetadataResolutionRequest */ MetadataResolutionRequest setRemoteRepositories( List remoteRepositories ); - /** - * Gets the repository cache to use. - * - * @return The repository cache to use or {@code null} if none. - */ - RepositoryCache getCache(); - - /** - * Sets the repository cache to use. - * - * @param cache The repository cache to use, may be {@code null}. - * @return This request, never {@code null}. - */ - MetadataResolutionRequest setCache( RepositoryCache cache ); - /** * Determines whether the managed version information should be retrieved. * diff --git a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java index dd15b13e98..31f6c8619f 100644 --- a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java +++ b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java @@ -1,5 +1,24 @@ package org.apache.maven; +/* + * 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. + */ + import java.io.File; import java.util.Arrays; import java.util.List; @@ -23,10 +42,12 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.repository.internal.MavenRepositorySystemSession; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.util.FileUtils; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; public abstract class AbstractCoreMavenComponentTestCase extends PlexusTestCase @@ -128,11 +149,24 @@ protected MavenSession createMavenSession( File pom, Properties executionPropert project.setPluginArtifactRepositories( request.getPluginArtifactRepositories() ); } - MavenSession session = new MavenSession( getContainer(), request, new DefaultMavenExecutionResult(), project ); + initRepoSession( configuration ); + + MavenSession session = + new MavenSession( getContainer(), configuration.getRepositorySession(), request, + new DefaultMavenExecutionResult() ); + session.setProjects( Arrays.asList( project ) ); return session; } + protected void initRepoSession( ProjectBuildingRequest request ) + { + File localRepo = new File( request.getLocalRepository().getBasedir() ); + MavenRepositorySystemSession session = new MavenRepositorySystemSession(); + session.setLocalRepositoryManager( new SimpleLocalRepositoryManager( localRepo ) ); + request.setRepositorySession( session ); + } + protected MavenProject createStubMavenProject() { Model model = new Model(); diff --git a/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java b/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java index 3fa4015f81..b220304cff 100644 --- a/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java +++ b/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java @@ -99,7 +99,7 @@ public void testDependencyInjection() request.setGoals( Arrays.asList( "validate" ) ); MavenExecutionResult result = maven.execute( request ); - assertFalse( result.hasExceptions() ); + assertFalse( result.getExceptions().toString(), result.hasExceptions() ); MavenProject project = result.getProject(); diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java b/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java new file mode 100644 index 0000000000..f9bbb2ba21 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java @@ -0,0 +1,77 @@ +package org.apache.maven.lifecycle; + +/* + * 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. + */ + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; + +/** + * @author Benjamin Bentmann + */ +public class EmptyLifecyclePluginAnalyzer + implements LifeCyclePluginAnalyzer +{ + public Set getPluginsBoundByDefaultToAllLifecycles( String packaging ) + { + Set plugins; + + // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests + if ( "JAR".equals( packaging ) ) + { + plugins = new LinkedHashSet(); + + plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) ); + plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) ); + plugins.add( newPlugin( "maven-surefire-plugin", "test" ) ); + plugins.add( newPlugin( "maven-jar-plugin", "jar" ) ); + plugins.add( newPlugin( "maven-install-plugin", "install" ) ); + plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) ); + } + else + { + plugins = Collections.emptySet(); + } + + return plugins; + } + + private Plugin newPlugin( String artifactId, String... goals ) + { + Plugin plugin = new Plugin(); + + plugin.setGroupId( "org.apache.maven.plugins" ); + plugin.setArtifactId( artifactId ); + + for ( String goal : goals ) + { + PluginExecution pluginExecution = new PluginExecution(); + pluginExecution.setId( "default-" + goal ); + pluginExecution.addGoal( goal ); + plugin.addExecution( pluginExecution ); + } + + return plugin; + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java index 177b5d54f9..b33649028f 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java @@ -26,16 +26,8 @@ import org.apache.maven.lifecycle.internal.MojoDescriptorCreator; import org.apache.maven.lifecycle.internal.TaskSegment; import org.apache.maven.model.Plugin; -import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginManagerException; -import org.apache.maven.plugin.PluginNotFoundException; -import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.descriptor.MojoDescriptor; -import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; -import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -306,10 +298,7 @@ public void testPluginConfigurationCreation() } MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) - throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, - MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, - PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException, - PluginVersionResolutionException + throws Exception { List taskSegments = lifeCycleTaskSegmentCalculator.calculateTaskSegments( session, Arrays.asList( tasks ) ); diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java index 4e738f791d..be148bd53e 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java @@ -1,3 +1,5 @@ +package org.apache.maven.lifecycle.internal.stub; + /* * 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 @@ -13,25 +15,17 @@ * the License. */ -package org.apache.maven.lifecycle.internal.stub; +import java.util.List; -import org.apache.maven.artifact.repository.RepositoryRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.BuildPluginManager; -import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginConfigurationException; -import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginManagerException; -import org.apache.maven.plugin.PluginNotFoundException; -import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; /** * @author Kristian Rosenvold @@ -40,28 +34,23 @@ public class BuildPluginManagerStub implements BuildPluginManager { - public PluginDescriptor loadPlugin( Plugin plugin, RepositoryRequest repositoryRequest ) - throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, - InvalidPluginDescriptorException + public PluginDescriptor loadPlugin( Plugin plugin, List repositories, RepositorySystemSession session ) { return null; } - public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryRequest repositoryRequest ) - throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, - MojoNotFoundException, InvalidPluginDescriptorException + public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List repositories, + RepositorySystemSession session ) { return MojoExecutorStub.createMojoDescriptor( plugin.getKey() ); } public ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor ) - throws PluginResolutionException, PluginManagerException { return null; } public void executeMojo( MavenSession session, MojoExecution execution ) - throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException { } } diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java index 7198fd29a2..e5dc526c8d 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java @@ -15,11 +15,11 @@ package org.apache.maven.lifecycle.internal.stub; -import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; import org.apache.maven.plugin.prefix.PluginPrefixRequest; import org.apache.maven.plugin.prefix.PluginPrefixResolver; import org.apache.maven.plugin.prefix.PluginPrefixResult; +import org.sonatype.aether.repository.ArtifactRepository; /** * @author Kristian Rosenvold diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java index 69f3e0b55f..b2daee2069 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java @@ -15,11 +15,11 @@ package org.apache.maven.lifecycle.internal.stub; -import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.version.PluginVersionRequest; import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.plugin.version.PluginVersionResolver; import org.apache.maven.plugin.version.PluginVersionResult; +import org.sonatype.aether.repository.ArtifactRepository; /** * @author Kristian Rosenvold diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java index 1c14822bcc..673e5387d3 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java @@ -20,17 +20,25 @@ import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.execution.MavenSession; +import org.apache.maven.project.DependencyResolutionException; +import org.apache.maven.project.DependencyResolutionRequest; +import org.apache.maven.project.DependencyResolutionResult; import org.apache.maven.project.MavenProject; +import org.sonatype.aether.graph.Dependency; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.util.graph.DefaultDependencyNode; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; /** * @author Kristian Rosenvold */ public class ProjectDependenciesResolverStub - implements ProjectDependenciesResolver + implements ProjectDependenciesResolver, org.apache.maven.project.ProjectDependenciesResolver { public Set resolve( MavenProject project, Collection scopesToResolve, MavenSession session ) throws ArtifactResolutionException, ArtifactNotFoundException @@ -59,4 +67,43 @@ public Set resolve( MavenProject project, Collection scopesToC { return new HashSet(); } + + public DependencyResolutionResult resolve( DependencyResolutionRequest request ) + throws DependencyResolutionException + { + return new DependencyResolutionResult() + { + + public List getUnresolvedDependencies() + { + return Collections.emptyList(); + } + + public List getResolvedDependencies() + { + return Collections.emptyList(); + } + + public List getResolutionErrors( Dependency dependency ) + { + return Collections.emptyList(); + } + + public DependencyNode getDependencyGraph() + { + return new DefaultDependencyNode( (Dependency) null ); + } + + public List getDependencies() + { + return Collections.emptyList(); + } + + public List getCollectionErrors() + { + return Collections.emptyList(); + } + }; + } + } diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java index b5feee5d37..1977be7aa5 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java @@ -216,7 +216,7 @@ public static MavenSession getMavenSession() MavenExecutionRequest mavenExecutionRequest = new DefaultMavenExecutionRequest(); mavenExecutionRequest.setExecutionListener( new AbstractExecutionListener() ); mavenExecutionRequest.setGoals( Arrays.asList( "clean", "aggr", "install" ) ); - final MavenSession session = new MavenSession( null, mavenExecutionRequest, defaultMavenExecutionResult ); + final MavenSession session = new MavenSession( null, null, mavenExecutionRequest, defaultMavenExecutionResult ); final ProjectDependencyGraphStub dependencyGraphStub = new ProjectDependencyGraphStub(); session.setProjectDependencyGraph( dependencyGraphStub ); session.setProjects( dependencyGraphStub.getSortedProjects() ); diff --git a/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java b/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java index 23e9e4a706..15ee576c6e 100644 --- a/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java +++ b/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java @@ -1,5 +1,24 @@ package org.apache.maven.plugin; +/* + * 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. + */ + import java.util.List; import org.apache.maven.AbstractCoreMavenComponentTestCase; @@ -39,16 +58,6 @@ protected String getProjectsDirectory() return "src/test/projects/plugin-manager"; } - private RepositoryRequest getRepositoryRequest( MavenSession session ) - { - RepositoryRequest request = new DefaultRepositoryRequest(); - - request.setLocalRepository( session.getLocalRepository() ); - request.setRemoteRepositories( session.getCurrentProject().getPluginArtifactRepositories() ); - - return request; - } - public void testPluginLoading() throws Exception { @@ -57,7 +66,9 @@ public void testPluginLoading() plugin.setGroupId( "org.apache.maven.its.plugins" ); plugin.setArtifactId( "maven-it-plugin" ); plugin.setVersion( "0.1" ); - PluginDescriptor pluginDescriptor = pluginManager.loadPlugin( plugin, getRepositoryRequest( session ) ); + PluginDescriptor pluginDescriptor = + pluginManager.loadPlugin( plugin, session.getCurrentProject().getRemotePluginRepositories(), + session.getRepositorySession() ); assertNotNull( pluginDescriptor ); } @@ -71,7 +82,9 @@ public void testMojoDescriptorRetrieval() plugin.setArtifactId( "maven-it-plugin" ); plugin.setVersion( "0.1" ); - MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( plugin, goal, getRepositoryRequest( session ) ); + MojoDescriptor mojoDescriptor = + pluginManager.getMojoDescriptor( plugin, goal, session.getCurrentProject().getRemotePluginRepositories(), + session.getRepositorySession() ); assertNotNull( mojoDescriptor ); assertEquals( goal, mojoDescriptor.getGoal() ); // igorf: plugin realm comes later @@ -229,7 +242,9 @@ public void testThatPluginDependencyThatHasSystemScopeIsResolved() repositoryRequest.setLocalRepository( getLocalRepository() ); repositoryRequest.setRemoteRepositories( getPluginArtifactRepositories() ); - PluginDescriptor pluginDescriptor = pluginManager.loadPlugin( plugin, getRepositoryRequest( session ) ); + PluginDescriptor pluginDescriptor = + pluginManager.loadPlugin( plugin, session.getCurrentProject().getRemotePluginRepositories(), + session.getRepositorySession() ); pluginManager.getPluginRealm( session, pluginDescriptor ); List artifacts = pluginDescriptor.getArtifacts(); diff --git a/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java index 36025f7da9..b3959c64e3 100644 --- a/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java +++ b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java @@ -27,6 +27,7 @@ import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.repository.internal.MavenRepositorySystemSession; import org.codehaus.plexus.PlexusTestCase; /** @@ -129,6 +130,7 @@ protected MavenProject getProjectWithDependencies( File pom ) configuration.setRemoteRepositories( Arrays.asList( new ArtifactRepository[] {} ) ); configuration.setProcessPlugins( false ); configuration.setResolveDependencies( true ); + initRepoSession( configuration ); try { @@ -157,8 +159,17 @@ protected MavenProject getProject( File pom ) { ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setLocalRepository( getLocalRepository() ); + initRepoSession( configuration ); return projectBuilder.build( pom, configuration ).getProject(); } + protected void initRepoSession( ProjectBuildingRequest request ) + { + File localRepo = new File( request.getLocalRepository().getBasedir() ); + MavenRepositorySystemSession repoSession = new MavenRepositorySystemSession(); + repoSession.setLocalRepositoryManager( new LegacyLocalRepositoryManager( localRepo ) ); + request.setRepositorySession( repoSession ); + } + } diff --git a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java index 44628c7425..7e000cf948 100644 --- a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java @@ -83,6 +83,7 @@ protected MavenProject getProject( Artifact pom, boolean allowStub ) { ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setLocalRepository( getLocalRepository() ); + initRepoSession( configuration ); return projectBuilder.build( pom, allowStub, configuration ).getProject(); } diff --git a/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java b/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java index 3d89ffa076..f396cdca9d 100644 --- a/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java +++ b/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java @@ -25,21 +25,11 @@ import java.util.Set; import org.apache.maven.execution.MavenSession; -import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.LifecycleExecutor; -import org.apache.maven.lifecycle.LifecycleNotFoundException; -import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException; import org.apache.maven.lifecycle.MavenExecutionPlan; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; -import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginNotFoundException; -import org.apache.maven.plugin.PluginResolutionException; -import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; -import org.apache.maven.plugin.version.PluginVersionResolutionException; /** * A stub implementation that assumes an empty lifecycle to bypass interaction with the plugin manager and to avoid @@ -52,8 +42,6 @@ public class EmptyLifecycleExecutor { public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) - throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, - MojoNotFoundException { return new MavenExecutionPlan(null, null, null, null ); } @@ -105,14 +93,10 @@ private Plugin newPlugin( String artifactId, String... goals ) } public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, - PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, - LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException { } public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws LifecycleExecutionException { return Collections.emptyList(); } diff --git a/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java b/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java index 547e55099a..e59988d84c 100644 --- a/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java +++ b/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java @@ -49,8 +49,8 @@ public List createArtifactRepositories( List pom } } - public ProjectRealmCache.CacheRecord createProjectRealm( MavenProject proejct, Model model, - ProjectBuildingRequest request ) + public ProjectRealmCache.CacheRecord createProjectRealm( MavenProject proejct, + Model model, ProjectBuildingRequest request ) { return new ProjectRealmCache.CacheRecord( null, null ); } diff --git a/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java b/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java new file mode 100644 index 0000000000..14b4c26e4c --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java @@ -0,0 +1,59 @@ +package org.apache.maven.project; + +/* + * 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. + */ + +import java.io.File; + +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; + +/** + * @author Benjamin Bentmann + */ +public class LegacyLocalRepositoryManager + extends SimpleLocalRepositoryManager +{ + + public LegacyLocalRepositoryManager( File basedir ) + { + super( basedir ); + } + + public String getPathForLocalArtifact( Artifact artifact ) + { + StringBuilder path = new StringBuilder( 128 ); + + path.append( artifact.getGroupId() ).append( '/' ); + + path.append( artifact.getExtension() ).append( 's' ).append( '/' ); + + path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() ); + + if ( artifact.getClassifier().length() > 0 ) + { + path.append( '-' ).append( artifact.getClassifier() ); + } + + path.append( '.' ).append( artifact.getExtension() ); + + return path.toString(); + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java index 0659b40659..2389e0d17f 100644 --- a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java @@ -32,7 +32,9 @@ import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.project.harness.PomTestWrapper; import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.repository.internal.MavenRepositorySystemSession; import org.codehaus.plexus.PlexusTestCase; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; public class PomConstructionTest extends PlexusTestCase @@ -1816,6 +1818,11 @@ private PomTestWrapper buildPom( String pomPath, boolean lenientValidation, Prop config.setUserProperties( executionProperties ); config.setValidationLevel( lenientValidation ? ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 : ModelBuildingRequest.VALIDATION_LEVEL_STRICT ); + MavenRepositorySystemSession repoSession = new MavenRepositorySystemSession(); + repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManager( + new File( + config.getLocalRepository().getBasedir() ) ) ); + config.setRepositorySession( repoSession ); return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() ); } diff --git a/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java b/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java new file mode 100644 index 0000000000..d48a3f2610 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java @@ -0,0 +1,115 @@ +package org.apache.maven.repository; + +/* + * 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. + */ + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; + +import org.codehaus.plexus.util.FileUtils; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.spi.connector.ArtifactDownload; +import org.sonatype.aether.spi.connector.ArtifactUpload; +import org.sonatype.aether.spi.connector.MetadataDownload; +import org.sonatype.aether.spi.connector.MetadataUpload; +import org.sonatype.aether.spi.connector.RepositoryConnector; +import org.sonatype.aether.transfer.ArtifactTransferException; + +/** + * @author Benjamin Bentmann + */ +public class TestRepositoryConnector + implements RepositoryConnector +{ + + private RemoteRepository repository; + + private File basedir; + + public TestRepositoryConnector( RemoteRepository repository ) + { + this.repository = repository; + try + { + basedir = FileUtils.toFile( new URL( repository.getUrl() ) ); + } + catch ( MalformedURLException e ) + { + throw new IllegalStateException( e ); + } + } + + public void close() + { + } + + public void get( Collection artifactDownloads, + Collection metadataDownloads ) + { + if ( artifactDownloads != null ) + { + for ( ArtifactDownload download : artifactDownloads ) + { + File remoteFile = new File( basedir, path( download.getArtifact() ) ); + try + { + FileUtils.copyFile( remoteFile, download.getFile() ); + } + catch ( IOException e ) + { + download.setException( new ArtifactTransferException( download.getArtifact(), repository, e ) ); + } + } + } + } + + private String path( Artifact artifact ) + { + StringBuilder path = new StringBuilder( 128 ); + + path.append( artifact.getGroupId().replace( '.', '/' ) ).append( '/' ); + + path.append( artifact.getArtifactId() ).append( '/' ); + + path.append( artifact.getBaseVersion() ).append( '/' ); + + path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() ); + + if ( artifact.getClassifier().length() > 0 ) + { + path.append( '-' ).append( artifact.getClassifier() ); + } + + path.append( '.' ).append( artifact.getExtension() ); + + return path.toString(); + } + + public void put( Collection artifactUploads, + Collection metadataUploads ) + { + // TODO Auto-generated method stub + + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java b/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java new file mode 100644 index 0000000000..008a83cbe9 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java @@ -0,0 +1,48 @@ +package org.apache.maven.repository; + +/* + * 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. + */ + +import org.codehaus.plexus.component.annotations.Component; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.spi.connector.RepositoryConnector; +import org.sonatype.aether.spi.connector.RepositoryConnectorFactory; +import org.sonatype.aether.transfer.NoRepositoryConnectorException; + +/** + * @author Benjamin Bentmann + */ +@Component( role = RepositoryConnectorFactory.class, hint = "test" ) +public class TestRepositoryConnectorFactory + implements RepositoryConnectorFactory +{ + + public RepositoryConnector newInstance( RepositorySystemSession session, RemoteRepository repository ) + throws NoRepositoryConnectorException + { + return new TestRepositoryConnector( repository ); + } + + public int getPriority() + { + return 0; + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java index 9cf7f89ff4..d17dd2397f 100644 --- a/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java +++ b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java @@ -31,11 +31,13 @@ import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.project.harness.PomTestWrapper; import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.repository.internal.MavenRepositorySystemSession; import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader; import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; public class PomConstructionWithSettingsTest extends PlexusTestCase @@ -111,6 +113,11 @@ private PomTestWrapper buildPom( String pomPath ) config.setLocalRepository( repositorySystem.createArtifactRepository( "local", localRepoUrl, new DefaultRepositoryLayout(), null, null ) ); config.setActiveProfileIds( settings.getActiveProfiles() ); + MavenRepositorySystemSession repoSession = new MavenRepositorySystemSession(); + repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManager( + new File( + config.getLocalRepository().getBasedir() ) ) ); + config.setRepositorySession( repoSession ); return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() ); } diff --git a/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml index c6769290d4..e052489bb6 100644 --- a/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml +++ b/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml @@ -2,8 +2,8 @@ - org.apache.maven.lifecycle.LifecycleExecutor - org.apache.maven.project.EmptyLifecycleExecutor + org.apache.maven.lifecycle.LifeCyclePluginAnalyzer + org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer diff --git a/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml b/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml index 2d4d20372d..e3c3ab340c 100644 --- a/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml +++ b/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml @@ -2,8 +2,8 @@ - org.apache.maven.lifecycle.LifecycleExecutor - org.apache.maven.project.EmptyLifecycleExecutor + org.apache.maven.lifecycle.LifeCyclePluginAnalyzer + org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer org.apache.maven.project.ProjectBuildingHelper diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/AbstractMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/AbstractMavenTransferListener.java index 312ec53f6b..56c07f288f 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/AbstractMavenTransferListener.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/AbstractMavenTransferListener.java @@ -24,111 +24,35 @@ import java.text.DecimalFormatSymbols; import java.util.Locale; -import org.apache.maven.repository.ArtifactTransferEvent; -import org.apache.maven.repository.ArtifactTransferListener; -import org.apache.maven.repository.ArtifactTransferResource; +import org.sonatype.aether.transfer.TransferEvent; +import org.sonatype.aether.transfer.TransferResource; +import org.sonatype.aether.util.listener.AbstractTransferListener; -public abstract class AbstractMavenTransferListener - implements ArtifactTransferListener +abstract class AbstractMavenTransferListener + extends AbstractTransferListener { protected PrintStream out; - private boolean showChecksumEvents; - protected AbstractMavenTransferListener( PrintStream out ) { this.out = ( out != null ) ? out : System.out; } - protected boolean showEvent( ArtifactTransferEvent event ) + public void transferInitiated( TransferEvent event ) { - if ( event.getResource() == null ) - { - return true; - } + String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading"; - String resource = event.getResource().getName(); - - if ( resource == null || resource.trim().length() == 0 ) - { - return true; - } - - if ( resource.endsWith( ".sha1" ) || resource.endsWith( ".md5" ) ) - { - return showChecksumEvents; - } - - return true; + out.println( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() ); } - public void transferInitiated( ArtifactTransferEvent transferEvent ) + public void transferSucceeded( TransferEvent event ) { - if ( !showEvent( transferEvent ) ) - { - return; - } - - doInitiated( transferEvent ); - } - - protected void doInitiated( ArtifactTransferEvent transferEvent ) - { - String message = - transferEvent.getRequestType() == ArtifactTransferEvent.REQUEST_PUT ? "Uploading" : "Downloading"; - - out.println( message + ": " + transferEvent.getResource().getUrl() ); - } - - public void transferStarted( ArtifactTransferEvent transferEvent ) - { - if ( !showEvent( transferEvent ) ) - { - return; - } - - doStarted( transferEvent ); - } - - protected void doStarted( ArtifactTransferEvent transferEvent ) - { - // to be overriden by sub classes - } - - public void transferProgress( ArtifactTransferEvent transferEvent ) - { - if ( !showEvent( transferEvent ) ) - { - return; - } - - doProgress( transferEvent ); - } - - protected void doProgress( ArtifactTransferEvent transferEvent ) - { - // to be overriden by sub classes - } - - public void transferCompleted( ArtifactTransferEvent transferEvent ) - { - if ( !showEvent( transferEvent ) ) - { - return; - } - - doCompleted( transferEvent ); - } - - protected void doCompleted( ArtifactTransferEvent transferEvent ) - { - ArtifactTransferResource artifact = transferEvent.getResource(); - long contentLength = transferEvent.getTransferredBytes(); + TransferResource artifact = event.getResource(); + long contentLength = event.getTransferredBytes(); if ( contentLength >= 0 ) { - String type = - ( transferEvent.getRequestType() == ArtifactTransferEvent.REQUEST_PUT ? "Uploaded" : "Downloaded" ); + String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" ); String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B"; String throughput = ""; @@ -140,7 +64,8 @@ protected void doCompleted( ArtifactTransferEvent transferEvent ) throughput = " at " + format.format( kbPerSec ) + " KB/sec"; } - out.println( type + ": " + artifact.getUrl() + " (" + len + throughput + ")" ); + out.println( type + ": " + artifact.getRepositoryUrl() + artifact.getResourceName() + " (" + len + + throughput + ")" ); } } @@ -149,14 +74,4 @@ protected long toKB( long bytes ) return ( bytes + 1023 ) / 1024; } - public boolean isShowChecksumEvents() - { - return showChecksumEvents; - } - - public void setShowChecksumEvents( boolean showChecksumEvents ) - { - this.showChecksumEvents = showChecksumEvents; - } - } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java index 103ede33c2..b0067105b0 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java @@ -23,8 +23,9 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.apache.maven.repository.ArtifactTransferEvent; -import org.apache.maven.repository.ArtifactTransferResource; +import org.sonatype.aether.transfer.TransferCancelledException; +import org.sonatype.aether.transfer.TransferEvent; +import org.sonatype.aether.transfer.TransferResource; /** * Console download progress meter. @@ -35,7 +36,7 @@ class ConsoleMavenTransferListener extends AbstractMavenTransferListener { - private Map downloads = new ConcurrentHashMap(); + private Map downloads = new ConcurrentHashMap(); private int lastLength; @@ -45,14 +46,15 @@ public ConsoleMavenTransferListener( PrintStream out ) } @Override - protected void doProgress( ArtifactTransferEvent transferEvent ) + public void transferProgressed( TransferEvent event ) + throws TransferCancelledException { - ArtifactTransferResource resource = transferEvent.getResource(); - downloads.put( resource, Long.valueOf( transferEvent.getTransferredBytes() ) ); + TransferResource resource = event.getResource(); + downloads.put( resource, Long.valueOf( event.getTransferredBytes() ) ); StringBuilder buffer = new StringBuilder( 64 ); - for ( Map.Entry entry : downloads.entrySet() ) + for ( Map.Entry entry : downloads.entrySet() ) { long total = entry.getKey().getContentLength(); long complete = entry.getValue().longValue(); @@ -100,16 +102,29 @@ private void pad( StringBuilder buffer, int spaces ) } @Override - public void transferCompleted( ArtifactTransferEvent transferEvent ) + public void transferSucceeded( TransferEvent event ) { - downloads.remove( transferEvent.getResource() ); + transferCompleted( event ); + + super.transferSucceeded( event ); + } + + @Override + public void transferFailed( TransferEvent event ) + { + transferCompleted( event ); + + super.transferFailed( event ); + } + + private void transferCompleted( TransferEvent event ) + { + downloads.remove( event.getResource() ); StringBuilder buffer = new StringBuilder( 64 ); pad( buffer, lastLength ); buffer.append( '\r' ); out.print( buffer ); - - super.transferCompleted( transferEvent ); } } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 3f43a38c94..56f5471f69 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -59,6 +59,7 @@ import org.codehaus.plexus.classworlds.ClassWorld; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.util.StringUtils; +import org.sonatype.aether.transfer.TransferListener; import org.sonatype.plexus.components.cipher.DefaultPlexusCipher; import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; @@ -760,11 +761,11 @@ else if ( profileAction.startsWith( "+" ) ) } } - ArtifactTransferListener transferListener; + TransferListener transferListener; if ( quiet ) { - transferListener = new QuietMavenTransferListener( cliRequest.stdout ); + transferListener = new QuietMavenTransferListener(); } else if ( request.isInteractiveMode() ) { @@ -775,8 +776,6 @@ else if ( request.isInteractiveMode() ) transferListener = new BatchModeMavenTransferListener( cliRequest.stdout ); } - transferListener.setShowChecksumEvents( false ); - String alternatePomFile = null; if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) ) { diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/QuietMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/QuietMavenTransferListener.java index 9e884042d7..094cb48f7c 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/QuietMavenTransferListener.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/QuietMavenTransferListener.java @@ -19,26 +19,13 @@ * under the License. */ -import java.io.PrintStream; - -import org.apache.maven.repository.ArtifactTransferEvent; +import org.sonatype.aether.util.listener.AbstractTransferListener; /** * @author Benjamin Bentmann */ class QuietMavenTransferListener - extends AbstractMavenTransferListener + extends AbstractTransferListener { - public QuietMavenTransferListener( PrintStream out ) - { - super( out ); - } - - @Override - protected boolean showEvent( ArtifactTransferEvent event ) - { - return false; - } - } diff --git a/maven-repository-metadata/pom.xml b/maven-repository-metadata/pom.xml index 4701874cef..489897bf25 100644 --- a/maven-repository-metadata/pom.xml +++ b/maven-repository-metadata/pom.xml @@ -46,7 +46,7 @@ under the License. org.codehaus.modello modello-maven-plugin - 1.0.0 + 1.1.0 src/main/mdo/metadata.mdo diff --git a/maven-repository-metadata/src/main/mdo/metadata.mdo b/maven-repository-metadata/src/main/mdo/metadata.mdo index 9af33257c3..3204475c12 100644 --- a/maven-repository-metadata/src/main/mdo/metadata.mdo +++ b/maven-repository-metadata/src/main/mdo/metadata.mdo @@ -19,7 +19,7 @@ under the License. repository-metadata Metadata @@ -33,29 +33,35 @@ under the License. Metadata - 1.0.0 + 1.0.0+ + + modelVersion + 1.1.0+ + String + The version of the underlying metadata model. + groupId - 1.0.0 + 1.0.0+ String The groupId that is directory represents, if any. artifactId - 1.0.0 + 1.0.0+ String The artifactId that is directory represents, if any. version - 1.0.0 + 1.0.0+ String The version that is directory represents, if any. versioning - 1.0.0 + 1.0.0+ Versioning @@ -63,7 +69,7 @@ under the License. plugins - 1.0.0 + 1.0.0+ The set of plugin mappings for the group Plugin @@ -73,7 +79,7 @@ under the License. - 1.0.0 + 1.0.0+ Versioning - 1.0.0 + 1.0.0+ Versioning information for an artifact latest - 1.0.0 + 1.0.0+ String What the latest version in the directory is, including snapshots release - 1.0.0 + 1.0.0+ String What the latest version in the directory is, of the releases snapshot - 1.0.0 + 1.0.0+ Snapshot @@ -225,7 +231,7 @@ under the License. versions - 1.0.0 + 1.0.0+ Versions available for the artifact String @@ -234,60 +240,95 @@ under the License. lastUpdated - 1.0.0 + 1.0.0+ String When the metadata was last updated + + snapshotVersions + 1.1.0+ + The snapshot versions available for the artifact. + + SnapshotVersion + * + + - 1.0.0 - - public void updateTimestamp() - { - setLastUpdatedTimestamp( new java.util.Date() ); - } + 1.0.0+ + + public void setLastUpdatedTimestamp( java.util.Date date ) + { + java.util.TimeZone timezone = java.util.TimeZone.getTimeZone( "UTC" ); + java.text.DateFormat fmt = new java.text.SimpleDateFormat( "yyyyMMddHHmmss" ); + fmt.setTimeZone( timezone ); + setLastUpdated( fmt.format( date ) ); + } + ]]> Snapshot - 1.0.0 + 1.0.0+ Snapshot data for the current version timestamp - 1.0.0 + 1.0.0+ The time it was deployed String buildNumber - 1.0.0 + 1.0.0+ The incremental build number int localCopy - 1.0.0 + 1.0.0+ Whether to use a local copy instead (with filename that includes the base version) boolean false + + SnapshotVersion + 1.1.0+ + Versioning information for a snapshot artifact. + + + classifier + 1.1.0+ + String + The classifier of the snapshot artifact this version information belongs to. + + + + version + 1.1.0+ + String + The resolved snapshot version of the artifact. + + + updated + 1.1.0+ + String + The timestamp when this version information was last updated. The timestamp is expressed using UTC in the format yyyyMMddHHmmss. + + + Plugin - 1.0.0 + 1.0.0+ Mapping information for a single plugin within this group NOTE: plugin version is _NOT_ included here, since it is resolved using a separate algorithm. @@ -295,21 +336,21 @@ under the License. name String true - 1.0.0 + 1.0.0+ Display name for the plugin. prefix String true - 1.0.0 + 1.0.0+ The plugin invocation prefix (i.e. eclipse for eclipse:eclipse) artifactId String true - 1.0.0 + 1.0.0+ The plugin artifactId diff --git a/pom.xml b/pom.xml index 7f224c2dbe..4e2682ab37 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ 1.4 1.4 1.3 + 1.1 true @@ -136,6 +137,7 @@ maven-settings maven-settings-builder maven-artifact + maven-aether-provider maven-repository-metadata maven-plugin-api maven-model-builder @@ -165,21 +167,6 @@ - - org.apache.maven - maven-lifecycle - ${project.version} - - - org.apache.maven - maven-reporting-api - ${project.version} - - - org.apache.maven - maven-profile - ${project.version} - org.apache.maven maven-model @@ -225,6 +212,11 @@ maven-artifact ${project.version} + + org.apache.maven + maven-aether-provider + ${project.version} + org.apache.maven maven-repository-metadata @@ -279,6 +271,33 @@ wagon-http-lightweight ${wagonVersion} + + + org.sonatype.aether + aether-api + ${aetherVersion} + + + org.sonatype.aether + aether-impl + ${aetherVersion} + + + org.sonatype.aether + aether-util + ${aetherVersion} + + + org.sonatype.aether + aether-connector-wagon + ${aetherVersion} + + + org.codehaus.plexus + plexus-container-default + + + commons-cli