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 72696bf80b..8f73426c8b 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 @@ -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 remoteRepositories, ArtifactRepository localRepository ) throws ProjectBuildingException diff --git a/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java b/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java index 2f9adf03e7..be05306fda 100644 --- a/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java +++ b/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java @@ -38,7 +38,7 @@ public interface MavenProjectBuilder throws ProjectBuildingException; //TODO remote-resources-plugin - MavenProject buildFromRepository( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository, boolean force ) + MavenProject buildFromRepository( Artifact artifact, List 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 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 da923ea6fb..182eb6392b 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 @@ -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( "" ); + buffer.append( "" ); + buffer.append( "4.0.0" ); + buffer.append( "" ).append( artifact.getGroupId() ).append( "" ); + buffer.append( "" ).append( artifact.getArtifactId() ).append( "" ); + buffer.append( "" ).append( artifact.getBaseVersion() ).append( "" ); + buffer.append( "" ).append( artifact.getType() ).append( "" ); + buffer.append( "" ); + + 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 build( List 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 activeProfiles = new ArrayList(); activeProfiles.addAll( result.getActivePomProfiles( result.getModelIds().get( 0 ) ) ); diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java index 770855a1fb..024a9ad6d9 100644 --- a/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java @@ -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 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 7a9942662f..44628c7425 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 @@ -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() 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 fc1d03732b..ccf45dea00 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 @@ -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 { diff --git a/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java b/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java index af57c82bf7..186c2697b6 100644 --- a/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java +++ b/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java @@ -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 ) ); diff --git a/maven-core/src/test/resources/org/apache/maven/MavenLifecycleParticipantTest.xml b/maven-core/src/test/resources/org/apache/maven/MavenLifecycleParticipantTest.xml new file mode 100644 index 0000000000..ebbbf7910a --- /dev/null +++ b/maven-core/src/test/resources/org/apache/maven/MavenLifecycleParticipantTest.xml @@ -0,0 +1,9 @@ + + + + + org.apache.maven.project.ProjectBuildingHelper + org.apache.maven.project.EmptyProjectBuildingHelper + + + diff --git a/maven-core/src/test/resources/org/apache/maven/lifecycle/LifecycleExecutorTest.xml b/maven-core/src/test/resources/org/apache/maven/lifecycle/LifecycleExecutorTest.xml new file mode 100644 index 0000000000..ebbbf7910a --- /dev/null +++ b/maven-core/src/test/resources/org/apache/maven/lifecycle/LifecycleExecutorTest.xml @@ -0,0 +1,9 @@ + + + + + org.apache.maven.project.ProjectBuildingHelper + org.apache.maven.project.EmptyProjectBuildingHelper + + + diff --git a/maven-core/src/test/resources/org/apache/maven/plugin/PluginManagerTest.xml b/maven-core/src/test/resources/org/apache/maven/plugin/PluginManagerTest.xml new file mode 100644 index 0000000000..ebbbf7910a --- /dev/null +++ b/maven-core/src/test/resources/org/apache/maven/plugin/PluginManagerTest.xml @@ -0,0 +1,9 @@ + + + + + org.apache.maven.project.ProjectBuildingHelper + org.apache.maven.project.EmptyProjectBuildingHelper + + + diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/StringModelSource.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/StringModelSource.java new file mode 100644 index 0000000000..3a7ab02fe4 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/StringModelSource.java @@ -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(); + } + +}