[MNG-4450] [regression] Stub project for missing dependency POMs is not properly created

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@881563 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Benjamin Bentmann 2009-11-17 22:05:28 +00:00
parent 669ab43ef2
commit 8b21cd1567
11 changed files with 203 additions and 85 deletions

View File

@ -23,10 +23,7 @@ import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.Repository;
import org.apache.maven.model.building.ModelBuildingException;
import org.apache.maven.model.building.ModelBuildingRequest;
@ -64,12 +61,12 @@ public class DefaultMavenProjectBuilder
return projectBuilder.build( pomFile, configuration ).getProject();
}
public MavenProject buildFromRepository( Artifact artifact, ProjectBuilderConfiguration configuration )
public MavenProject buildFromRepository( Artifact artifact, ProjectBuilderConfiguration configuration, boolean allowStubModel )
throws ProjectBuildingException
{
normalizeToArtifactRepositories( configuration );
return projectBuilder.build( artifact, configuration ).getProject();
return projectBuilder.build( artifact, allowStubModel, configuration ).getProject();
}
private void normalizeToArtifactRepositories( ProjectBuilderConfiguration configuration )
@ -152,7 +149,7 @@ public class DefaultMavenProjectBuilder
try
{
return buildFromRepository( artifact, configuration );
return buildFromRepository( artifact, configuration, allowStubModel );
}
catch ( ProjectBuildingException e )
{
@ -160,42 +157,11 @@ public class DefaultMavenProjectBuilder
{
throw new InvalidProjectModelException( e.getProjectId(), e.getMessage(), e.getPomFile() );
}
else if ( e.getCause() instanceof MultipleArtifactsNotFoundException )
{
if ( allowStubModel )
{
MavenProject stubProject = new MavenProject( createStubModel( artifact ) );
stubProject.setParent( buildStandaloneSuperProject( configuration ) );
return stubProject;
}
}
throw e;
}
}
private Model createStubModel( Artifact projectArtifact )
{
Model model = new Model();
model.setModelVersion( "4.0.0" );
model.setArtifactId( projectArtifact.getArtifactId() );
model.setGroupId( projectArtifact.getGroupId() );
model.setVersion( projectArtifact.getVersion() );
// TODO: not correct in some instances
model.setPackaging( projectArtifact.getType() );
model.setDistributionManagement( new DistributionManagement() );
model.getDistributionManagement().setStatus( "generated" );
return model;
}
public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository )
throws ProjectBuildingException

View File

@ -38,7 +38,7 @@ public interface MavenProjectBuilder
throws ProjectBuildingException;
//TODO remote-resources-plugin
MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository, boolean force )
MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository, boolean allowStubModel )
throws ProjectBuildingException;
// TODO: this is only to provide a project for plugins that don't need a project to execute but need some

View File

@ -38,6 +38,8 @@ import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelBuildingResult;
import org.apache.maven.model.building.ModelProblem;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.model.building.ModelSource;
import org.apache.maven.model.building.StringModelSource;
import org.apache.maven.model.building.UrlModelSource;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.project.artifact.ProjectArtifact;
@ -77,13 +79,12 @@ public class DefaultProjectBuilder
public ProjectBuildingResult build( File pomFile, ProjectBuildingRequest configuration )
throws ProjectBuildingException
{
return build( pomFile, true, configuration );
return build( pomFile, new FileModelSource( pomFile ), configuration );
}
private ProjectBuildingResult build( File pomFile, boolean localProject, ProjectBuildingRequest configuration )
private ProjectBuildingResult build( File pomFile, ModelSource modelSource, ProjectBuildingRequest configuration )
throws ProjectBuildingException
{
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
try
@ -102,14 +103,8 @@ public class DefaultProjectBuilder
new DefaultModelBuildingListener( project, projectBuildingHelper, configuration );
request.setModelBuildingListener( listener );
if ( localProject )
{
request.setPomFile( pomFile );
}
else
{
request.setModelSource( new FileModelSource( pomFile ) );
}
request.setPomFile( pomFile );
request.setModelSource( modelSource );
ModelBuildingResult result;
try
@ -192,6 +187,12 @@ public class DefaultProjectBuilder
public ProjectBuildingResult build( Artifact artifact, ProjectBuildingRequest configuration )
throws ProjectBuildingException
{
return build( artifact, false, configuration );
}
public ProjectBuildingResult build( Artifact artifact, boolean allowStubModel, ProjectBuildingRequest configuration )
throws ProjectBuildingException
{
if ( !artifact.getType().equals( "pom" ) )
{
@ -209,6 +210,11 @@ public class DefaultProjectBuilder
ArtifactResolutionResult result = repositorySystem.resolve( request );
if ( result.hasMissingArtifacts() && allowStubModel )
{
return build( null, createStubModelSource( artifact ), configuration );
}
try
{
resolutionErrorHandler.throwErrors( request, result );
@ -221,7 +227,25 @@ public class DefaultProjectBuilder
boolean localProject = artifact.getRepository() != null && "reactor".equals( artifact.getRepository().getId() );
return build( artifact.getFile(), localProject, configuration );
File pomFile = artifact.getFile();
return build( localProject ? pomFile : null, new FileModelSource( pomFile ), configuration );
}
private ModelSource createStubModelSource( Artifact artifact )
{
StringBuilder buffer = new StringBuilder( 1024 );
buffer.append( "<?xml version='1.0'?>" );
buffer.append( "<project>" );
buffer.append( "<modelVersion>4.0.0</modelVersion>" );
buffer.append( "<groupId>" ).append( artifact.getGroupId() ).append( "</groupId>" );
buffer.append( "<artifactId>" ).append( artifact.getArtifactId() ).append( "</artifactId>" );
buffer.append( "<version>" ).append( artifact.getBaseVersion() ).append( "</version>" );
buffer.append( "<packaging>" ).append( artifact.getType() ).append( "</packaging>" );
buffer.append( "</project>" );
return new StringModelSource( buffer, artifact.getId() );
}
/**
@ -233,35 +257,10 @@ public class DefaultProjectBuilder
public ProjectBuildingResult buildStandaloneSuperProject( ProjectBuildingRequest config )
throws ProjectBuildingException
{
ModelBuildingRequest request = getModelBuildingRequest( config, null );
MavenProject standaloneProject = new MavenProject( repositorySystem, this, config );
DefaultModelBuildingListener listener =
new DefaultModelBuildingListener( standaloneProject, projectBuildingHelper, config );
request.setModelBuildingListener( listener );
request.setModelSource( new UrlModelSource( getClass().getResource( "standalone.xml" ) ) );
ModelBuildingResult result;
try
{
result = modelBuilder.build( request );
}
catch ( ModelBuildingException e )
{
throw new ProjectBuildingException( "[standalone]", "Failed to build standalone project", e );
}
standaloneProject.setModel( result.getEffectiveModel() );
standaloneProject.setOriginalModel( result.getRawModel() );
standaloneProject.setActiveProfiles( result.getActiveExternalProfiles() );
standaloneProject.setInjectedProfileIds( "external", getProfileIds( result.getActiveExternalProfiles() ) );
standaloneProject.setExecutionRoot( true );
return new DefaultProjectBuildingResult( standaloneProject, result.getProblems(), null );
ProjectBuildingResult result =
build( null, new UrlModelSource( getClass().getResource( "standalone.xml" ) ), config );
result.getProject().setExecutionRoot( true );
return result;
}
public List<ProjectBuildingResult> build( List<File> pomFiles, boolean recursive, ProjectBuildingRequest config )
@ -493,10 +492,13 @@ public class DefaultProjectBuilder
project.getPackaging() );
project.setArtifact( projectArtifact );
Build build = project.getBuild();
project.addScriptSourceRoot( build.getScriptSourceDirectory() );
project.addCompileSourceRoot( build.getSourceDirectory() );
project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
if ( project.getFile() != null )
{
Build build = project.getBuild();
project.addScriptSourceRoot( build.getScriptSourceDirectory() );
project.addCompileSourceRoot( build.getSourceDirectory() );
project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
}
List<Profile> activeProfiles = new ArrayList<Profile>();
activeProfiles.addAll( result.getActivePomProfiles( result.getModelIds().get( 0 ) ) );

View File

@ -29,6 +29,9 @@ public interface ProjectBuilder
ProjectBuildingResult build( Artifact projectArtifact, ProjectBuildingRequest request )
throws ProjectBuildingException;
ProjectBuildingResult build( Artifact projectArtifact, boolean allowStubModel, ProjectBuildingRequest request )
throws ProjectBuildingException;
// TODO: this is only to provide a project for plugins that don't need a project to execute but need some
// of the values from a MavenProject. Ideally this should be something internal and nothing outside Maven
// would ever need this so it should not be exposed in a public API

View File

@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.codehaus.plexus.util.FileUtils;
@ -77,6 +78,15 @@ public class DefaultMavenProjectBuilderTest
}
}
protected MavenProject getProject( Artifact pom, boolean allowStub )
throws Exception
{
ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
configuration.setLocalRepository( getLocalRepository() );
return projectBuilder.build( pom, allowStub, configuration ).getProject();
}
/**
* Check that we can build ok from the middle pom of a (parent,child,grandchild) heirarchy
* @throws Exception
@ -104,6 +114,25 @@ public class DefaultMavenProjectBuilderTest
assertEquals( "first", project.getBuildPlugins().get( 0 ).getExecutions().get( 0 ).getId() );
}
public void testBuildStubModelForMissingRemotePom()
throws Exception
{
Artifact pom = repositorySystem.createProjectArtifact( "org.apache.maven.its", "missing", "0.1" );
MavenProject project = getProject( pom, true );
assertNotNull( project.getArtifactId() );
assertNotNull( project.getRemoteArtifactRepositories() );
assertFalse( project.getRemoteArtifactRepositories().isEmpty() );
assertNotNull( project.getPluginArtifactRepositories() );
assertFalse( project.getPluginArtifactRepositories().isEmpty() );
assertNull( project.getParent() );
assertNull( project.getParentArtifact() );
assertFalse( project.isExecutionRoot() );
}
@Override
protected ArtifactRepository getLocalRepository()

View File

@ -26,14 +26,12 @@ import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.RepositoryRequest;
import org.apache.maven.model.Model;
import org.apache.maven.model.Repository;
import org.codehaus.plexus.component.annotations.Component;
/**
* A stub implementation to bypass artifact resolution from repositories.
*
* @author Benjamin Bentmann
*/
@Component( role = ProjectBuildingHelper.class )
public class EmptyProjectBuildingHelper
implements ProjectBuildingHelper
{

View File

@ -269,6 +269,11 @@ public class TestRepositorySystem
if ( !localFile.exists() )
{
if ( request.getRemoteRepositories().isEmpty() )
{
throw new IOException( localFile + " does not exist and no remote repositories are configured" );
}
ArtifactRepository remoteRepo = request.getRemoteRepositories().get( 0 );
File remoteFile = new File( remoteRepo.getBasedir(), remoteRepo.pathOf( artifact ) );

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<plexus>
<components>
<component>
<role>org.apache.maven.project.ProjectBuildingHelper</role>
<implementation>org.apache.maven.project.EmptyProjectBuildingHelper</implementation>
</component>
</components>
</plexus>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<plexus>
<components>
<component>
<role>org.apache.maven.project.ProjectBuildingHelper</role>
<implementation>org.apache.maven.project.EmptyProjectBuildingHelper</implementation>
</component>
</components>
</plexus>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<plexus>
<components>
<component>
<role>org.apache.maven.project.ProjectBuildingHelper</role>
<implementation>org.apache.maven.project.EmptyProjectBuildingHelper</implementation>
</component>
</components>
</plexus>

View File

@ -0,0 +1,88 @@
package org.apache.maven.model.building;
/*
* 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.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Wraps an ordinary {@link CharSequence} as a model source.
*
* @author Benjamin Bentmann
*/
public class StringModelSource
implements ModelSource
{
private String pom;
private String location;
/**
* Creates a new model source backed by the specified string.
*
* @param pom The POM's string representation, may be empty or {@code null}.
*/
public StringModelSource( CharSequence pom )
{
this( pom, null );
}
/**
* Creates a new model source backed by the specified string.
*
* @param pom The POM's string representation, may be empty or {@code null}.
* @param location The location to report for this use, may be {@code null}.
*/
public StringModelSource( CharSequence pom, String location )
{
this.pom = ( pom != null ) ? pom.toString() : "";
this.location = ( location != null ) ? location : "(memory)";
}
public InputStream getInputStream()
throws IOException
{
return new ByteArrayInputStream( pom.getBytes( "UTF-8" ) );
}
public String getLocation()
{
return location;
}
/**
* Gets the character sequence of this model source.
*
* @return The underlying character stream, never {@code null}.
*/
public String getModel()
{
return pom;
}
@Override
public String toString()
{
return getLocation();
}
}