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 8fc35e8adc..ee82c1d93c 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -41,8 +41,6 @@ import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.MavenExecutionRequest; -import org.apache.maven.execution.MavenExecutionRequestPopulationException; -import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ProjectDependencyGraph; @@ -116,9 +114,6 @@ public class DefaultMaven @Requirement protected PlexusContainer container; - @Requirement - MavenExecutionRequestPopulator populator; - @Requirement private ExecutionEventCatapult eventCatapult; @@ -146,22 +141,19 @@ public class DefaultMaven @Requirement private SessionScope sessionScope; + @Override public MavenExecutionResult execute( MavenExecutionRequest request ) { MavenExecutionResult result; try { - result = doExecute( populator.populateDefaults( request ) ); + result = doExecute( request ); } catch ( OutOfMemoryError e ) { result = addExceptionToResult( new DefaultMavenExecutionResult(), e ); } - catch ( MavenExecutionRequestPopulationException e ) - { - result = addExceptionToResult( new DefaultMavenExecutionResult(), e ); - } catch ( RuntimeException e ) { result = diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java index bb794eeef5..dc2521c672 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java +++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java @@ -20,7 +20,10 @@ */ import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -30,16 +33,29 @@ import javax.inject.Inject; import javax.inject.Named; +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.InvalidRepositoryException; +import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; +import org.apache.maven.artifact.repository.MavenArtifactRepository; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout2; import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.repository.RepositorySystem; +// +// All of this needs to go away and be couched in terms of the execution request +// import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Repository; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; import org.apache.maven.settings.SettingsUtils; +// +// Settings in core +// import org.apache.maven.toolchain.model.PersistedToolchains; import org.apache.maven.toolchain.model.ToolchainModel; import org.codehaus.plexus.util.StringUtils; @@ -49,12 +65,16 @@ public class DefaultMavenExecutionRequestPopulator implements MavenExecutionRequestPopulator { - private final RepositorySystem repositorySystem; + private static final String WILDCARD = "*"; + private static final String EXTERNAL_WILDCARD = "external:*"; + + private final Map layouts; + @Inject - public DefaultMavenExecutionRequestPopulator( RepositorySystem repositorySystem ) + public DefaultMavenExecutionRequestPopulator( RepositorySystem repositorySystem, Map layouts ) { - this.repositorySystem = repositorySystem; + this.layouts = layouts; } @Override @@ -182,6 +202,29 @@ public MavenExecutionRequest populateFromToolchains( MavenExecutionRequest reque return request; } + @Override + public MavenExecutionRequest populateDefaults( MavenExecutionRequest request ) + throws MavenExecutionRequestPopulationException + { + baseDirectory( request ); + + localRepository( request ); + + populateDefaultPluginGroups( request ); + + injectDefaultRepositories( request ); + + injectDefaultPluginRepositories( request ); + + processRepositoriesInSettings( request ); + + return request; + } + + // + // + // + private void populateDefaultPluginGroups( MavenExecutionRequest request ) { request.addPluginGroup( "org.apache.maven.plugins" ); @@ -197,9 +240,9 @@ private void injectDefaultRepositories( MavenExecutionRequest request ) { try { - request.addRemoteRepository( repositorySystem.createDefaultRemoteRepository() ); + request.addRemoteRepository( createDefaultRemoteRepository( request ) ); } - catch ( InvalidRepositoryException e ) + catch ( Exception e ) { throw new MavenExecutionRequestPopulationException( "Cannot create default remote repository.", e ); } @@ -215,15 +258,37 @@ private void injectDefaultPluginRepositories( MavenExecutionRequest request ) { try { - request.addPluginArtifactRepository( repositorySystem.createDefaultRemoteRepository() ); + request.addPluginArtifactRepository( createDefaultRemoteRepository( request ) ); } - catch ( InvalidRepositoryException e ) + catch ( Exception e ) { throw new MavenExecutionRequestPopulationException( "Cannot create default remote repository.", e ); } } } + private ArtifactRepository createDefaultRemoteRepository( MavenExecutionRequest request ) + throws Exception + { + return createRepository( request, RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID, + true, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, false, + ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, + ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN ); + } + + private ArtifactRepository createRepository( MavenExecutionRequest request, String url, String repositoryId, boolean releases, + String releaseUpdates, boolean snapshots, String snapshotUpdates, + String checksumPolicy ) throws Exception + { + ArtifactRepositoryPolicy snapshotsPolicy = + new ArtifactRepositoryPolicy( snapshots, snapshotUpdates, checksumPolicy ); + + ArtifactRepositoryPolicy releasesPolicy = + new ArtifactRepositoryPolicy( releases, releaseUpdates, checksumPolicy ); + + return createArtifactRepository( repositoryId, url, "default", snapshotsPolicy, releasesPolicy, request ); + } + private Set getRepoIds( List repositories ) { Set repoIds = new HashSet(); @@ -242,17 +307,48 @@ private Set getRepoIds( List repositories ) private void processRepositoriesInSettings( MavenExecutionRequest request ) throws MavenExecutionRequestPopulationException { - repositorySystem.injectMirror( request.getRemoteRepositories(), request.getMirrors() ); - repositorySystem.injectProxy( request.getRemoteRepositories(), request.getProxies() ); - repositorySystem.injectAuthentication( request.getRemoteRepositories(), request.getServers() ); - - request.setRemoteRepositories( repositorySystem.getEffectiveRepositories( request.getRemoteRepositories() ) ); - - repositorySystem.injectMirror( request.getPluginArtifactRepositories(), request.getMirrors() ); - repositorySystem.injectProxy( request.getPluginArtifactRepositories(), request.getProxies() ); - repositorySystem.injectAuthentication( request.getPluginArtifactRepositories(), request.getServers() ); - - request.setPluginArtifactRepositories( repositorySystem.getEffectiveRepositories( request.getPluginArtifactRepositories() ) ); + // + // + // + // + // central + // + // http://10.0.1.34:62247/ + // central + // + // + // + // + // true + // http + // localhost + // 62248 + // 10.0.1.34 + // + // + // + // + // it-defaults + // + // + // + // + // it-defaults + // + // + // + // Turns + // + // http://repo1.maven.org/maven2 + // + // to + // + // http://10.0.1.34:62247/ + // + // Not sure why the DefaultMirrorSelector doesn't do this... + // + injectMirror( request, request.getRemoteRepositories(), request.getMirrors() ); + injectMirror( request, request.getPluginArtifactRepositories(), request.getMirrors() ); } private void localRepository( MavenExecutionRequest request ) @@ -281,7 +377,7 @@ private void localRepository( MavenExecutionRequest request ) // Artifact Transfer Mechanism // ------------------------------------------------------------------------ - public ArtifactRepository createLocalRepository( MavenExecutionRequest request ) + private ArtifactRepository createLocalRepository( MavenExecutionRequest request ) throws MavenExecutionRequestPopulationException { String localRepositoryPath = null; @@ -298,9 +394,9 @@ public ArtifactRepository createLocalRepository( MavenExecutionRequest request ) try { - return repositorySystem.createLocalRepository( new File( localRepositoryPath ) ); + return createLocalRepository( request, new File( localRepositoryPath ) ); } - catch ( InvalidRepositoryException e ) + catch ( Exception e ) { throw new MavenExecutionRequestPopulationException( "Cannot create local repository.", e ); } @@ -313,23 +409,344 @@ private void baseDirectory( MavenExecutionRequest request ) request.setBaseDirectory( request.getPom().getAbsoluteFile().getParentFile() ); } } - - public MavenExecutionRequest populateDefaults( MavenExecutionRequest request ) - throws MavenExecutionRequestPopulationException + + // + // Code taken from LegacyRepositorySystem + // + + private ArtifactRepository createLocalRepository( MavenExecutionRequest request, File localRepository ) + throws Exception { - baseDirectory( request ); + return createRepository( request, "file://" + localRepository.toURI().getRawPath(), + RepositorySystem.DEFAULT_LOCAL_REPO_ID, true, + ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true, + ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, + ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE ); + } + + private void injectMirror( MavenExecutionRequest request, List repositories, List mirrors ) + { + if ( repositories != null && mirrors != null ) + { + for ( ArtifactRepository repository : repositories ) + { + Mirror mirror = getMirror( repository, mirrors ); + injectMirror( request, repository, mirror ); + } + } + } - localRepository( request ); + private void injectMirror( MavenExecutionRequest request, ArtifactRepository repository, Mirror mirror ) + { + if ( mirror != null ) + { + ArtifactRepository original = + createArtifactRepository( repository.getId(), repository.getUrl(), repository.getLayout(), + repository.getSnapshots(), repository.getReleases(), request ); - populateDefaultPluginGroups( request ); + repository.setMirroredRepositories( Collections.singletonList( original ) ); - injectDefaultRepositories( request ); + repository.setId( mirror.getId() ); + repository.setUrl( mirror.getUrl() ); - injectDefaultPluginRepositories( request ); + if ( StringUtils.isNotEmpty( mirror.getLayout() ) ) + { + repository.setLayout( getLayout( mirror.getLayout() ) ); + } + } + } + + private ArtifactRepositoryLayout getLayout( String id ) + { + ArtifactRepositoryLayout layout = layouts.get( id ); - processRepositoriesInSettings( request ); + if ( layout == null ) + { + layout = new UnknownRepositoryLayout( id, layouts.get( "default" ) ); + } - return request; + return layout; } + /** + * In the future, the legacy system might encounter repository types for which no layout components exists because + * the actual communication with the repository happens via a repository connector. As a minimum, the legacy system + * needs to retain the id of this layout so that the content type of the remote repository can still be accurately + * described. + */ + private static class UnknownRepositoryLayout + implements ArtifactRepositoryLayout + { + + private final String id; + + private final ArtifactRepositoryLayout fallback; + + public UnknownRepositoryLayout( String id, ArtifactRepositoryLayout fallback ) + { + this.id = id; + this.fallback = fallback; + } + + @Override + public String getId() + { + return id; + } + + @Override + public String pathOf( Artifact artifact ) + { + return fallback.pathOf( artifact ); + } + + @Override + public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository ) + { + return fallback.pathOfLocalRepositoryMetadata( metadata, repository ); + } + + @Override + public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata ) + { + return fallback.pathOfRemoteRepositoryMetadata( metadata ); + } + + @Override + public String toString() + { + return getId(); + } + } + + // + // ArtifactRepositoryFactory + // + private ArtifactRepository createArtifactRepository( String id, String url, String layoutId, + ArtifactRepositoryPolicy snapshots, + ArtifactRepositoryPolicy releases, + MavenExecutionRequest request ) + throws Exception + { + ArtifactRepositoryLayout layout = layouts.get( layoutId ); + + checkLayout( id, layoutId, layout ); + + return createArtifactRepository( id, url, layout, snapshots, releases, request ); + } + + private ArtifactRepository createArtifactRepository( String id, String url, + ArtifactRepositoryLayout repositoryLayout, + ArtifactRepositoryPolicy snapshots, + ArtifactRepositoryPolicy releases, + MavenExecutionRequest request ) + { + String globalChecksumPolicy = request.getGlobalChecksumPolicy(); + + if ( snapshots == null ) + { + snapshots = new ArtifactRepositoryPolicy(); + } + + if ( releases == null ) + { + releases = new ArtifactRepositoryPolicy(); + } + + if ( globalChecksumPolicy != null ) + { + snapshots.setChecksumPolicy( globalChecksumPolicy ); + releases.setChecksumPolicy( globalChecksumPolicy ); + } + + ArtifactRepository repository; + if ( repositoryLayout instanceof ArtifactRepositoryLayout2 ) + { + repository = + ( (ArtifactRepositoryLayout2) repositoryLayout ).newMavenArtifactRepository( id, url, snapshots, + releases ); + } + else + { + repository = new MavenArtifactRepository( id, url, repositoryLayout, snapshots, releases ); + } + + return repository; + } + + private void checkLayout( String repositoryId, String layoutId, ArtifactRepositoryLayout layout ) + throws Exception + { + if ( layout == null ) + { + throw new Exception( String.format( "Cannot find ArtifactRepositoryLayout instance for: %s %s", layoutId, repositoryId ) ); + } + } + + // + // MirrorSelector + // + private Mirror getMirror( ArtifactRepository repository, List mirrors ) + { + String repoId = repository.getId(); + + if ( repoId != null && mirrors != null ) + { + for ( Mirror mirror : mirrors ) + { + if ( repoId.equals( mirror.getMirrorOf() ) && matchesLayout( repository, mirror ) ) + { + return mirror; + } + } + + for ( Mirror mirror : mirrors ) + { + if ( matchPattern( repository, mirror.getMirrorOf() ) && matchesLayout( repository, mirror ) ) + { + return mirror; + } + } + } + + return null; + } + + /** + * This method checks if the pattern matches the originalRepository. Valid patterns: * = + * everything external:* = everything not on the localhost and not file based. repo,repo1 = repo + * or repo1 *,!repo1 = everything except repo1 + * + * @param originalRepository to compare for a match. + * @param pattern used for match. Currently only '*' is supported. + * @return true if the repository is a match to this pattern. + */ + private boolean matchPattern( ArtifactRepository originalRepository, String pattern ) + { + boolean result = false; + String originalId = originalRepository.getId(); + + // simple checks first to short circuit processing below. + if ( WILDCARD.equals( pattern ) || pattern.equals( originalId ) ) + { + result = true; + } + else + { + // process the list + String[] repos = pattern.split( "," ); + for ( String repo : repos ) + { + repo = repo.trim(); + // see if this is a negative match + if ( repo.length() > 1 && repo.startsWith( "!" ) ) + { + if ( repo.substring( 1 ).equals( originalId ) ) + { + // explicitly exclude. Set result and stop processing. + result = false; + break; + } + } + // check for exact match + else if ( repo.equals( originalId ) ) + { + result = true; + break; + } + // check for external:* + else if ( EXTERNAL_WILDCARD.equals( repo ) && isExternalRepo( originalRepository ) ) + { + result = true; + // don't stop processing in case a future segment explicitly excludes this repo + } + else if ( WILDCARD.equals( repo ) ) + { + result = true; + // don't stop processing in case a future segment explicitly excludes this repo + } + } + } + return result; + } + + /** + * Checks the URL to see if this repository refers to an external repository + * + * @param originalRepository + * @return true if external. + */ + private boolean isExternalRepo( ArtifactRepository originalRepository ) + { + try + { + URL url = new URL( originalRepository.getUrl() ); + return !( url.getHost().equals( "localhost" ) || url.getHost().equals( "127.0.0.1" ) + || url.getProtocol().equals( "file" ) ); + } + catch ( MalformedURLException e ) + { + // bad url just skip it here. It should have been validated already, but the wagon lookup will deal with it + return false; + } + } + + private boolean matchesLayout( ArtifactRepository repository, Mirror mirror ) + { + return matchesLayout( RepositoryUtils.getLayout( repository ), mirror.getMirrorOfLayouts() ); + } + + /** + * Checks whether the layouts configured for a mirror match with the layout of the repository. + * + * @param repoLayout The layout of the repository, may be {@code null}. + * @param mirrorLayout The layouts supported by the mirror, may be {@code null}. + * @return {@code true} if the layouts associated with the mirror match the layout of the original repository, + * {@code false} otherwise. + */ + private boolean matchesLayout( String repoLayout, String mirrorLayout ) + { + boolean result = false; + + // simple checks first to short circuit processing below. + if ( StringUtils.isEmpty( mirrorLayout ) || WILDCARD.equals( mirrorLayout ) ) + { + result = true; + } + else if ( mirrorLayout.equals( repoLayout ) ) + { + result = true; + } + else + { + // process the list + String[] layouts = mirrorLayout.split( "," ); + for ( String layout : layouts ) + { + // see if this is a negative match + if ( layout.length() > 1 && layout.startsWith( "!" ) ) + { + if ( layout.substring( 1 ).equals( repoLayout ) ) + { + // explicitly exclude. Set result and stop processing. + result = false; + break; + } + } + // check for exact match + else if ( layout.equals( repoLayout ) ) + { + result = true; + break; + } + else if ( WILDCARD.equals( layout ) ) + { + result = true; + // don't stop processing in case a future segment explicitly excludes this repo + } + } + } + + return result; + } } 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 15e20825e2..2b2a1d829b 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 @@ -29,9 +29,13 @@ import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.model.Profile; import org.apache.maven.project.ProjectBuildingRequest; +// +// These settings values need to be removed and pushed down into a provider of configuration information +// import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; +// import org.apache.maven.toolchain.model.ToolchainModel; import org.codehaus.plexus.logging.Logger; import org.eclipse.aether.RepositoryCache; diff --git a/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java b/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java index 5019c7fdb8..67f4deef90 100644 --- a/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java +++ b/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java @@ -33,7 +33,7 @@ public class DefaultMavenExecutionRequestPopulatorTest extends TestCase { DefaultMavenExecutionRequestPopulator testee = - new DefaultMavenExecutionRequestPopulator( new TestRepositorySystem() ); + new DefaultMavenExecutionRequestPopulator( new TestRepositorySystem(), null ); public void testPluginRepositoryInjection() throws Exception 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 5b7bd7fab3..35ccbd2794 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 @@ -56,6 +56,7 @@ import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.ExecutionListener; import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequestPopulationException; import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.lifecycle.LifecycleExecutionException; @@ -410,6 +411,7 @@ private PlexusContainer container( CliRequest cliRequest ) container = new DefaultPlexusContainer( cc, new AbstractModule() { + @Override protected void configure() { bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory ); @@ -590,11 +592,13 @@ private void repository( CliRequest cliRequest ) } } - private int execute( CliRequest cliRequest ) + private int execute( CliRequest cliRequest ) throws MavenExecutionRequestPopulationException { - eventSpyDispatcher.onEvent( cliRequest.request ); + MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request ); + + eventSpyDispatcher.onEvent( request ); - MavenExecutionResult result = maven.execute( cliRequest.request ); + MavenExecutionResult result = maven.execute( request ); eventSpyDispatcher.onEvent( result ); @@ -1160,14 +1164,13 @@ else if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) if ( localRepoProperty == null ) { localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY ); - } - + } + if ( localRepoProperty != null ) { request.setLocalRepositoryPath( localRepoProperty ); } - request.setCacheNotFound( true ); request.setCacheTransferError( false );