Index: maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java
===================================================================
--- maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java (revision 510454)
+++ maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java (working copy)
@@ -86,6 +86,8 @@
private Map metadataMap;
private boolean optional;
+
+ private String modelRepresentation;
public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
String classifier, ArtifactHandler artifactHandler )
@@ -584,4 +586,14 @@
{
this.optional = optional;
}
+
+ public String getModelRepresentation()
+ {
+ return modelRepresentation;
+ }
+
+ public void setModelRepresentation( String modelRepresentation )
+ {
+ this.modelRepresentation = modelRepresentation;
+ }
}
Index: maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java
===================================================================
--- maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java (revision 510454)
+++ maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java (working copy)
@@ -167,4 +167,9 @@
boolean isSelectedVersionKnown()
throws OverConstrainedVersionException;
+
+ // For MNG-624, we sometimes need a slightly modified model to install and deploy
+ String getModelRepresentation();
+
+ void setModelRepresentation( String modelRepresentation );
}
\ No newline at end of file
Index: maven-artifact-manager/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java
===================================================================
--- maven-artifact-manager/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java (revision 510454)
+++ maven-artifact-manager/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java (working copy)
@@ -68,16 +68,30 @@
try
{
+ // This updates the artifact and causes the artifactFile (below) location computation to likely change (especially for snapshots)
transformationManager.transformForDeployment( artifact, deploymentRepository, localRepository );
- // Copy the original file to the new one if it was transformed
+ // A location in the local repository to stash our artifact before uploading
File artifactFile = new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) );
- if ( !artifactFile.equals( source ) )
+
+ if ( "pom".equals( artifact.getType() ) && artifact.getModelRepresentation() != null )
{
- FileUtils.copyFile( source, artifactFile );
+ // MNG-624: Need to use our expanded model that includes the proper entries
+ FileUtils.fileWrite( artifactFile.getAbsolutePath(), artifact.getModelRepresentation() );
+
+ // Need to put the artifactFile we just wrote, not the source
+ // Note: The source for a pom is the file you edit, don't want to change it!
+ wagonManager.putArtifact( artifactFile, artifact, deploymentRepository );
}
+ else
+ {
+ if ( !artifactFile.equals( source ) )
+ {
+ FileUtils.copyFile( source, artifactFile );
+ }
- wagonManager.putArtifact( source, artifact, deploymentRepository );
+ wagonManager.putArtifact( source, artifact, deploymentRepository );
+ }
// must be after the artifact is installed
for ( Iterator i = artifact.getMetadataList().iterator(); i.hasNext(); )
Index: maven-artifact-manager/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java
===================================================================
--- maven-artifact-manager/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java (revision 510454)
+++ maven-artifact-manager/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java (working copy)
@@ -68,10 +68,20 @@
destination.getParentFile().mkdirs();
}
- getLogger().info( "Installing " + source.getPath() + " to " + destination );
+ if ( "pom".equals( artifact.getType() ) && artifact.getModelRepresentation() != null )
+ {
+ getLogger().info( "Installing expanded " + source.getPath() + " to " + destination );
- FileUtils.copyFile( source, destination );
+ // For MNG-624, we cannot always just copy the pom if part of the was inferred and computed
+ FileUtils.fileWrite( destination.getAbsolutePath(), artifact.getModelRepresentation() );
+ }
+ else
+ {
+ getLogger().info( "Installing " + source.getPath() + " to " + destination );
+ FileUtils.copyFile( source, destination );
+ }
+
// must be after the artifact is installed
for ( Iterator i = artifact.getMetadataList().iterator(); i.hasNext(); )
{
Index: maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java
===================================================================
--- maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java (revision 510454)
+++ maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java (working copy)
@@ -47,6 +47,7 @@
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.Repository;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.profiles.DefaultProfileManager;
import org.apache.maven.profiles.MavenProfilesBuilder;
import org.apache.maven.profiles.ProfileManager;
@@ -115,6 +116,7 @@
* inheritance
* interpolation
+ * validate inheritance (so variables and missing elements can be applied to )
* defaults injection
* path translation
@@ -131,6 +133,14 @@
*/
/**
+ * Read in a model (pom.xml) from disk, local or remote repository and build a project from it.
+ *
+ * In the process of processing the model, parent-models will be found and relevant things extracted:
+ * variables, profiles, plugins, dependencies.
+ *
+ * Sub-modules are processed by L{org.apache.maven.DefaultMaven} which is generally what calls into
+ * this class regardless.
+ *
* @version $Id: DefaultMavenProjectBuilder.java,v 1.37 2005/03/08 01:55:22
* trygvis Exp $
*/
@@ -280,7 +290,8 @@
try
{
- project = processProjectLogic( "", project, null, null, true );
+ project = expandProjectDefinition( project, null, null, true );
+ processProjectLogic( "", project );
project.setExecutionRoot( true );
@@ -709,19 +720,20 @@
}
project.setOriginalModel( originalModel );
-
- rawProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), new MavenProject( project ) );
+ MavenProject rawProject = new MavenProject( project ); // Non-interpolated read-only wo/parent
+
// we don't have to force the collision exception for superModel here, it's already been done in getSuperModel()
MavenProject previousProject = superProject;
- Model previous = superProject.getModel();
+ Model previous = superProject.getModel(); // parent
+ // Using information from a project's lineage, fix any missing attributes in models (modifying them)
for ( Iterator i = lineage.iterator(); i.hasNext(); )
{
MavenProject currentProject = (MavenProject) i.next();
- Model current = currentProject.getModel();
+ Model current = currentProject.getModel(); // child
String pathAdjustment = null;
@@ -757,19 +769,66 @@
try
{
- project = processProjectLogic( pomLocation, project, externalProfileManager, projectDir, strict );
+ project = expandProjectDefinition( project, externalProfileManager, projectDir, strict );
+
+ // Fixup/validate parent if we had any variables in the version strings initially
+ validateImpliedInheritance( project, pomLocation, externalProfileManager, strict );
+
+ if ( originalModel.getParent() != null && !isParentIdExpanded( originalModel.getParent() ) )
+ {
+ // If we had to fix the implied inheritance and in the process patch our version or group, we may need
+ // to expand again to ensure any thing like ${pom.version} in dependencies, etc. is properly expanded
+ project = expandProjectDefinition( project, externalProfileManager, projectDir, strict );
+ }
}
catch ( ModelInterpolationException e )
{
throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
}
+
+ // Finish processing the project logic...
+ try
+ {
+ processProjectLogic( pomLocation, project );
+ }
catch ( InvalidRepositoryException e )
{
throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
}
- processedProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project );
+
+ if ( ( originalModel.getParent() != null && !isParentIdExpanded( originalModel.getParent() ) ) ) // || !isModelIdExpanded( originalModel ) )
+ {
+ // Write a modified data segment to the artifact
+ Model newModel = ModelUtils.cloneModel( originalModel );
+ newModel.setParent( project.getModel().getParent() );
+ newModel.setGroupId( project.getGroupId() );
+ newModel.setVersion( project.getVersion() );
+
+ StringWriter sWriter = new StringWriter();
+ MavenXpp3Writer writer = new MavenXpp3Writer();
+ try
+ {
+ writer.write( sWriter, newModel );
+ }
+ catch ( IOException e )
+ {
+ throw new ProjectBuildingException( projectId, "Cannot serialize modified model", e );
+ }
+
+ sWriter.write( "\n\n" );
+
+ getLogger().debug( "New model:\n" + sWriter.toString() );
+
+ project.getArtifact().setModelRepresentation( sWriter.toString() );
+ }
+
+ String cacheKey = createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+
+ rawProjectCache.put( cacheKey, rawProject ); // do it here after version's been expanded
+ processedProjectCache.put( cacheKey, project );
+
// jvz:note
// this only happens if we are building from a source file
if ( projectDescriptor != null )
@@ -793,7 +852,7 @@
if ( rawParent != null )
{
- String cacheKey = createCacheKey( rawParent.getGroupId(), rawParent.getArtifactId(), rawParent.getVersion() );
+ cacheKey = createCacheKey( rawParent.getGroupId(), rawParent.getArtifactId(), rawParent.getVersion() );
MavenProject processedParent = (MavenProject) processedProjectCache.get( cacheKey );
@@ -806,7 +865,115 @@
return project;
}
+
+ /**
+ * If the project's parent definition or its actual parent had any variables in their definition or any missing
+ * details, assembleLineage() would have had to guess at who our parent was. This routine verifies who our parent
+ * really is and makes sure that missing details are filled-in and any variables are suitably expanded.
+ */
+ private void validateImpliedInheritance(MavenProject project, String pomLocation, ProfileManager externalProfileManager, boolean strict)
+ throws ProjectBuildingException, InvalidProjectModelException
+ {
+ Parent projectModelParent = project.getModel().getParent();
+ MavenProject candidateParentProject = project.getParent();
+ if ( projectModelParent != null && candidateParentProject != null && candidateParentProject.getModel() != null )
+ {
+ Model candidateParentModel = candidateParentProject.getOriginalModel();
+ if ( candidateParentModel == null )
+ {
+ candidateParentModel = project.getParent().getModel();
+ }
+
+ Parent originalProjectModelParent = null;
+ if ( project.getOriginalModel() != null )
+ {
+ originalProjectModelParent = project.getOriginalModel().getParent();
+ }
+
+ String version = fixParentVersion( project );
+ String groupId = fixParentGroupId( project );
+ fixParentArtifactId( project );
+
+ if ( originalProjectModelParent != null && ( !isParentIdExpanded( originalProjectModelParent ) || !isModelIdExpanded( candidateParentModel ) ) )
+ {
+ // Now that our model has been expanded (interpolated + profiles injected, etc.), parent-version will be expanded
+ String parentKey = createCacheKey( projectModelParent.getGroupId(), projectModelParent.getArtifactId(), projectModelParent.getVersion() );
+
+ // Try to get the processed (interpolated, etc.) parent
+ MavenProject parentProject = (MavenProject) processedProjectCache.get( parentKey );
+
+ if ( parentProject != null )
+ {
+ // We have the parent, we just weren't able to match it before, but now we can
+ project.setParent( new MavenProject( parentProject ) ); // expanded read-only wo/parent
+
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "Found " + project.getId() + "'s parent: " + parentProject.getId() );
+ }
+ }
+ else
+ {
+ // We're probably running mvn below the parent, so we've probably just read the parent pom.xml in when building lineage
+ // Thus, we need to expand/interpolate the parent so we can properly compare versions to ensure they match
+ try
+ {
+ candidateParentProject = project.getParent(); // non-expanded
+ candidateParentProject = expandProjectDefinition( candidateParentProject, externalProfileManager, candidateParentProject.getFile(), strict );
+ boolean reExpand = false;
+
+ // It is quite possible that the candidate tried to inherit its version too...
+ if ( StringUtils.isEmpty( candidateParentProject.getVersion() ) )
+ {
+ candidateParentProject.setVersion( version );
+ reExpand = true;
+ }
+
+ if ( StringUtils.isEmpty( candidateParentProject.getGroupId() ) )
+ {
+ candidateParentProject.setGroupId( groupId );
+ reExpand = true;
+ }
+
+ if ( reExpand )
+ {
+ candidateParentProject = expandProjectDefinition( candidateParentProject, externalProfileManager, candidateParentProject.getFile(), strict );
+ }
+ }
+ catch ( ModelInterpolationException e )
+ {
+ throw new ProjectBuildingException( project.getId(), "Unable to expand " + project.getId() + "'s pom.xml.", e );
+ }
+
+ // Now validate that everything matches
+ if ( !projectModelParent.getGroupId().equals( candidateParentProject.getGroupId() ) ||
+ !projectModelParent.getArtifactId().equals( candidateParentProject.getArtifactId() ) ||
+ !projectModelParent.getVersion().equals( candidateParentProject.getVersion() ) )
+ {
+ throw new ProjectBuildingException( project.getId(), "Unable to find parent for " + project.getId() +
+ "\n Specified: " + projectModelParent.getId() +
+ "\n Found: " + candidateParentProject.getId() );
+ }
+
+ project.setParent( candidateParentProject );
+
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "Interpolated and matched " + project.getId() + "'s candidate parent: " + candidateParentProject.getId() );
+ }
+ }
+
+ if ( project.getGroupId().equals( project.getParent().getGroupId() ) &&
+ project.getArtifactId().equals( project.getParent().getArtifactId() ) )
+ {
+ throw new ProjectBuildingException( project.getId(), "Parent groupId/artifactId in '" + pomLocation +
+ "' is a duplicate of the current project" );
+ }
+ }
+ }
+ }
+
private String safeVersionlessKey( String groupId, String artifactId )
{
String gid = groupId;
@@ -842,18 +1009,16 @@
}
/**
- * @todo can this take in a model instead of a project and still be successful?
- * @todo In fact, does project REALLY need a MavenProject as a parent? Couldn't it have just a wrapper around a
- * model that supported parents which were also the wrapper so that inheritence was assembled. We don't really need
- * the resolved source roots, etc for the parent - that occurs for the parent when it is constructed independently
- * and projects are not cached or reused
+ * Return a new project based on an interpolated model that's had the active profiles injected.
+ *
+ * @param project The unexpanded (original) maven project
+ * @param profileMgr The profile manager
+ * @param projectDir The directory for this maven project
+ * @param strict Should we be strict processing the pom.xml?
+ * @return A new project based on the expanded project/model definition
*/
- private MavenProject processProjectLogic( String pomLocation,
- MavenProject project,
- ProfileManager profileMgr,
- File projectDir,
- boolean strict )
- throws ProjectBuildingException, ModelInterpolationException, InvalidRepositoryException
+ private MavenProject expandProjectDefinition( MavenProject project, ProfileManager profileMgr, File projectDir, boolean strict )
+ throws ProjectBuildingException, ModelInterpolationException
{
Model model = project.getModel();
@@ -904,11 +1069,38 @@
project.setActiveProfiles( activeProfiles );
+ project.setParent( parentProject );
+
+ return project;
+ }
+
+ /**
+ * @todo can this take in a model instead of a project and still be successful?
+ * @todo In fact, does project REALLY need a MavenProject as a parent? Couldn't it have just a wrapper around a
+ * model that supported parents which were also the wrapper so that inheritence was assembled. We don't really need
+ * the resolved source roots, etc for the parent - that occurs for the parent when it is constructed independently
+ * and projects are not cached or reused
+ */
+ private void processProjectLogic( String pomLocation, MavenProject project )
+ throws ProjectBuildingException, InvalidRepositoryException
+ {
+ MavenProject parentProject = project.getParent();
+
// TODO: maybe not strictly correct, while we should enfore that packaging has a type handler of the same id, we don't
Artifact projectArtifact = artifactFactory.createBuildArtifact( project.getGroupId(), project.getArtifactId(),
project.getVersion(), project.getPackaging() );
project.setArtifact( projectArtifact );
+ if ( parentProject != null )
+ {
+ Artifact parentArtifact = artifactFactory.createParentArtifact( parentProject.getGroupId(),
+ parentProject.getArtifactId(),
+ parentProject.getVersion() );
+ project.setParentArtifact( parentArtifact );
+ }
+
+ Model model = project.getModel();
+
project.setPluginArtifactRepositories( ProjectUtils.buildArtifactRepositories( model.getPluginRepositories(),
artifactRepositoryFactory,
container ) );
@@ -929,16 +1121,6 @@
}
}
- project.setParent( parentProject );
-
- if ( parentProject != null )
- {
- Artifact parentArtifact = artifactFactory.createParentArtifact( parentProject.getGroupId(),
- parentProject.getArtifactId(),
- parentProject.getVersion() );
- project.setParentArtifact( parentArtifact );
- }
-
// Must validate before artifact construction to make sure dependencies are good
ModelValidationResult validationResult = validator.validate( model );
@@ -959,8 +1141,6 @@
project.setReportArtifacts( createReportArtifacts( projectId, project.getReportPlugins() ) );
project.setExtensionArtifacts( createExtensionArtifacts( projectId, project.getBuildExtensions() ) );
-
- return project;
}
/**
@@ -1026,6 +1206,12 @@
}
MavenProject project = new MavenProject( model );
+
+ // If building from the middle of a lineage (i.e. child in a parent-child-grandchild project), child will be found in rawProjectCache,
+ // but without this, its parent may not be found in cache. Thus, location of pom.xml is important. And it can't be a directory as
+ // despite user documentation saying otherwise, there are a number of places in maven where File.getParent() is called assuming it
+ // will retrieve the directory where the pom.xml is stored.
+ project.setFile( new File( projectDir, "pom.xml" ) );
project.setActiveProfiles( activeProfiles );
@@ -1037,31 +1223,28 @@
{
String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
- if ( StringUtils.isEmpty( parentModel.getGroupId() ) )
+ if ( isParentIdExpanded( parentModel ) && isModelIdExpanded( model ) &&
+ parentModel.getGroupId().equals( model.getGroupId() ) &&
+ parentModel.getArtifactId().equals( model.getArtifactId() ) )
{
- throw new ProjectBuildingException( projectId, "Missing groupId element from parent element" );
+ throw new ProjectBuildingException( projectId, "Parent groupId/artifactId in '" + project.getFile() +
+ "' is a duplicate of the current project" );
}
- else if ( StringUtils.isEmpty( parentModel.getArtifactId() ) )
- {
- throw new ProjectBuildingException( projectId, "Missing artifactId element from parent element" );
- }
- else if ( parentModel.getGroupId().equals( model.getGroupId() ) &&
- parentModel.getArtifactId().equals( model.getArtifactId() ) )
- {
- throw new ProjectBuildingException( projectId, "Parent element is a duplicate of " + "the current project " );
- }
- else if ( StringUtils.isEmpty( parentModel.getVersion() ) )
- {
- throw new ProjectBuildingException( projectId, "Missing version element from parent element" );
- }
// the only way this will have a value is if we find the parent on disk...
File parentDescriptor = null;
model = null;
+ MavenProject parentProject = null;
+
String parentKey = createCacheKey( parentModel.getGroupId(), parentModel.getArtifactId(), parentModel.getVersion() );
- MavenProject parentProject = (MavenProject) rawProjectCache.get( parentKey );
+
+ // If none of the parent needs to be interpolated, look up in the rawProjectCache
+ if ( isParentIdExpanded( parentModel ) )
+ {
+ parentProject = (MavenProject) rawProjectCache.get( parentKey );
+ }
if ( parentProject != null )
{
@@ -1121,21 +1304,20 @@
{
Model candidateParent = readModel( projectId, parentDescriptor, strict );
- String candidateParentGroupId = candidateParent.getGroupId();
- if ( candidateParentGroupId == null && candidateParent.getParent() != null )
+ if ( !isParentIdExpanded( parentModel ) || !isModelIdExpanded( candidateParent ) )
{
- candidateParentGroupId = candidateParent.getParent().getGroupId();
+ // Just use POM we found above us. We'll validate everything later
+ model = candidateParent;
+
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "Using parent-POM from the project hierarcy for " +
+ project.getId() + " but id must still be validated." );
+ }
}
-
- String candidateParentVersion = candidateParent.getVersion();
- if ( candidateParentVersion == null && candidateParent.getParent() != null )
- {
- candidateParentVersion = candidateParent.getParent().getVersion();
- }
-
- if ( parentModel.getGroupId().equals( candidateParentGroupId ) &&
+ else if ( parentModel.getGroupId().equals( getModelGroupId( candidateParent ) ) &&
parentModel.getArtifactId().equals( candidateParent.getArtifactId() ) &&
- parentModel.getVersion().equals( candidateParentVersion ) )
+ parentModel.getVersion().equals( getModelVersion( candidateParent ) ) )
{
model = candidateParent;
@@ -1160,6 +1342,25 @@
// only resolve the parent model from the repository system if we didn't find it on disk...
if ( model == null )
{
+ if ( !isParentIdExpanded( parentModel ) )
+ {
+ // Very hackish, but just in case var is defined in system properties... try to expand it
+ try
+ {
+ MavenProject tmpProj = expandProjectDefinition( project, externalProfileManager, project.getFile(), strict );
+ Parent tmpParent = tmpProj.getModel().getParent();
+
+ if ( isParentIdExpanded( tmpParent ) )
+ {
+ parentModel = tmpParent;
+ }
+ }
+ catch ( ModelInterpolationException e )
+ {
+ getLogger().debug( "Unable to expand " + project.getId() + " when fetching parent from repository." );
+ }
+ }
+
// MNG-2302: parent's File was being populated incorrectly when parent is loaded from repo.
// keep this in line with other POMs loaded from the repository...the file should be null.
parentDescriptor = null;
@@ -1205,8 +1406,8 @@
projectId + " has wrong packaging: " + model.getPackaging() + ". Must be 'pom'." );
}
- File parentProjectDir = null;
- if ( parentDescriptor != null )
+ File parentProjectDir = parentDescriptor;
+ if ( parentDescriptor != null && !parentDescriptor.isDirectory() ) // We test elsewhere that descriptor is a dir, test here too
{
parentProjectDir = parentDescriptor.getParentFile();
}
@@ -1371,6 +1572,227 @@
}
}
+ /**
+ * If the parent version is empty, find it in the parent-pom(s) and repair it in our project.
+ */
+ private String fixParentVersion( MavenProject project ) throws ProjectBuildingException
+ {
+ Parent projectModelParent = project.getModel().getParent();
+ String version = projectModelParent.getVersion();
+
+ // If our project has no version, walk up our parents until we find one
+ if ( StringUtils.isEmpty( version ) )
+ {
+ version = findParentVersion( project );
+
+ if ( StringUtils.isEmpty( version ) )
+ {
+ throw new ProjectBuildingException( project.getId(), "Unable to find version in parent pom-s" );
+ }
+
+ if ( StringUtils.isEmpty( project.getVersion() ) )
+ {
+ // If our version was being implied from the parent version, then set our version
+ project.setVersion( version );
+ }
+
+ projectModelParent.setVersion( version );
+ }
+
+ return version;
+ }
+
+ /**
+ * If the parent groupId is empty, find it in the parent-pom(s) and repair it in our project.
+ */
+ private String fixParentGroupId( MavenProject project ) throws ProjectBuildingException
+ {
+ Parent parent = project.getModel().getParent();
+ String groupId = parent.getGroupId();
+
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ groupId = findParentGroupId( project );
+
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ throw new ProjectBuildingException( project.getId(), "Unable to find groupId in parent pom-s" );
+ }
+
+ if ( StringUtils.isEmpty( project.getGroupId() ) )
+ {
+ // If our groupId was being implied from the parent groupId, then set our groupId
+ project.setGroupId( groupId );
+ }
+
+ parent.setGroupId( groupId );
+ }
+
+ return groupId;
+ }
+
+ /**
+ * If the parent artifactId is empty, find it in the parent-pom(s) and repair it in our project.
+ */
+ private String fixParentArtifactId( MavenProject project ) throws ProjectBuildingException
+ {
+ Parent parent = project.getModel().getParent();
+ String artifactId = parent.getArtifactId();
+
+ if ( StringUtils.isEmpty( artifactId ) )
+ {
+ artifactId = findParentArtifactId( project );
+
+ if ( StringUtils.isEmpty( artifactId ) )
+ {
+ throw new ProjectBuildingException( project.getId(), "Unable to find artifactId in parent pom-s" );
+ }
+
+ parent.setArtifactId( artifactId );
+ }
+
+ return artifactId;
+ }
+
+ /**
+ * Recurse up our lineage (parents) until we find a parent whose version is specified.
+ */
+ private String findParentVersion( MavenProject project )
+ {
+ getLogger().debug( project.getId() + ": looking for parent version" );
+ MavenProject candidateParentProject = project.getParent();
+
+ if ( candidateParentProject == null )
+ {
+ getLogger().debug( project.getId() + ": found no parent!");
+ return null; // no more parents to chase down! User probably didn't put a version anywhere!
+ }
+
+ String version = candidateParentProject.getVersion();
+
+ if ( StringUtils.isEmpty( version ) )
+ {
+ return findParentVersion( candidateParentProject );
+ }
+
+ getLogger().debug( "" + project.getId() + ": returning ver from " + candidateParentProject.getId() );
+
+ return version;
+ }
+
+ /**
+ * Recurse up our lineage (parents) until we find a parent whose groupId is specified.
+ */
+ private String findParentGroupId( MavenProject project )
+ {
+ MavenProject candidateParentProject = project.getParent();
+
+ if ( candidateParentProject == null )
+ {
+ return null; // no more parents to chase down
+ }
+
+ String groupId = candidateParentProject.getGroupId();
+
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ return findParentGroupId( candidateParentProject );
+ }
+
+ return groupId;
+ }
+
+ /**
+ * Recurse up our lineage (parents) until we find a parent whose artifactId is specified.
+ */
+ private String findParentArtifactId( MavenProject project )
+ {
+ MavenProject candidateParentProject = project.getParent();
+
+ if ( candidateParentProject == null )
+ {
+ return null; // no more parents to chase down
+ }
+
+ String artifactId = candidateParentProject.getArtifactId();
+
+ if ( StringUtils.isEmpty( artifactId ) )
+ {
+ return findParentArtifactId( candidateParentProject );
+ }
+
+ return artifactId;
+ }
+
+ /**
+ * Return true if there are no more variables to be expanded in a model's parent tags.
+ *
+ * Note that this will also return false if there is a variable that simply cannot be expanded because it is not defined
+ * or was misspelled, etc.
+ *
+ * @param parent a model's parent tag
+ * @return true if there are no more variables to be expanded in a model's parent tags.
+ */
+ private static boolean isParentIdExpanded( Parent parent )
+ {
+ return ( !StringUtils.isEmpty( parent.getVersion() ) &&
+ !StringUtils.isEmpty( parent.getGroupId() ) &&
+ !StringUtils.isEmpty( parent.getArtifactId() ) &&
+ parent.getVersion().indexOf( "${" ) == -1 &&
+ parent.getGroupId().indexOf( "${" ) == -1 &&
+ parent.getArtifactId().indexOf( "${" ) == -1 );
+ }
+
+ /**
+ * Return true if there are no more variables to be expanded the tags that comprise an artifact definition.
+ *
+ * Note that this will also return false if there is a variable that simply cannot be expanded because it is not defined
+ * or was misspelled, etc.
+ *
+ * @param model the model to inspect
+ * @return true if there are no more variables to be expanded in the definition of a model's artifact.
+ */
+ private static boolean isModelIdExpanded( Model model )
+ {
+ String version = getModelVersion( model );
+ String groupId = getModelGroupId( model );
+ String artifactId = model.getArtifactId(); // should never be empty/missing
+
+ return ( !StringUtils.isEmpty( version ) &&
+ !StringUtils.isEmpty( groupId ) &&
+ version.indexOf( "${" ) == -1 &&
+ groupId.indexOf( "${" ) == -1 &&
+ artifactId.indexOf( "${" ) == -1 );
+ }
+
+ /**
+ * Sometimes a model's GroupId is specified only in its parent. Fetch whatever we can find.
+ */
+ private static String getModelGroupId( Model model )
+ {
+ if ( model != null && model.getGroupId() != null )
+ return model.getGroupId();
+
+ if ( model == null || model.getParent() == null )
+ return null;
+
+ return model.getParent().getGroupId();
+ }
+
+ /**
+ * Sometimes a model's Version is specified only in its parent. Fetch whatever we can find.
+ */
+ private static String getModelVersion( Model model )
+ {
+ if ( model != null && model.getVersion() != null )
+ return model.getVersion();
+
+ if ( model == null || model.getParent() == null )
+ return null;
+
+ return model.getParent().getVersion();
+ }
+
private static String createCacheKey( String groupId, String artifactId, String version )
{
return groupId + ":" + artifactId + ":" + version;
Index: maven-project/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java
===================================================================
--- maven-project/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java (revision 510454)
+++ maven-project/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java (working copy)
@@ -49,6 +49,8 @@
private final MavenProject project;
+ private String modelRepresentation;
+
public ActiveProjectArtifact( MavenProject project, Artifact artifact )
{
this.artifact = artifact;
@@ -296,4 +298,14 @@
{
artifact.setOptional( optional );
}
+
+ public String getModelRepresentation()
+ {
+ return modelRepresentation;
+ }
+
+ public void setModelRepresentation( String modelRepresentation )
+ {
+ this.modelRepresentation = modelRepresentation;
+ }
}
Index: maven-project/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java
===================================================================
--- maven-project/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java (revision 510454)
+++ maven-project/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java (working copy)
@@ -80,20 +80,34 @@
File destination = new File( localRepository.getBasedir(),
localRepository.pathOfLocalRepositoryMetadata( this, remoteRepository ) );
- // ----------------------------------------------------------------------------
- // I'm fully aware that the file could just be moved using File.rename but
- // there are bugs in various JVM that have problems doing this across
- // different filesystem. So we'll incur the small hit to actually copy
- // here and be safe. jvz.
- // ----------------------------------------------------------------------------
-
- try
+ if ( artifact.getModelRepresentation() != null )
{
- FileUtils.copyFile( file, destination );
+ try
+ {
+ FileUtils.fileWrite( destination.getAbsolutePath(), artifact.getModelRepresentation() );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryMetadataStoreException( "Error writing POM to the local repository.", e );
+ }
}
- catch ( IOException e )
+ else
{
- throw new RepositoryMetadataStoreException( "Error copying POM to the local repository.", e );
+ // ----------------------------------------------------------------------------
+ // I'm fully aware that the file could just be moved using File.rename but
+ // there are bugs in various JVM that have problems doing this across
+ // different filesystem. So we'll incur the small hit to actually copy
+ // here and be safe. jvz.
+ // ----------------------------------------------------------------------------
+
+ try
+ {
+ FileUtils.copyFile( file, destination );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryMetadataStoreException( "Error copying POM to the local repository.", e );
+ }
}
}