| 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.apache.maven.artifact.Artifact; |
| import org.apache.maven.artifact.ArtifactStatus; |
| import org.apache.maven.artifact.ArtifactUtils; |
| import org.apache.maven.artifact.InvalidRepositoryException; |
| import org.apache.maven.artifact.manager.WagonManager; |
| import org.apache.maven.artifact.metadata.ArtifactMetadataSource; |
| import org.apache.maven.artifact.repository.ArtifactRepository; |
| import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; |
| import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; |
| import org.apache.maven.artifact.resolver.ArtifactNotFoundException; |
| import org.apache.maven.artifact.resolver.ArtifactResolutionException; |
| import org.apache.maven.artifact.resolver.ArtifactResolutionResult; |
| import org.apache.maven.artifact.resolver.ArtifactResolver; |
| import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; |
| import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; |
| import org.apache.maven.artifact.versioning.ManagedVersionMap; |
| import org.apache.maven.artifact.versioning.VersionRange; |
| import org.apache.maven.model.Build; |
| import org.apache.maven.model.Dependency; |
| import org.apache.maven.model.DependencyManagement; |
| import org.apache.maven.model.DistributionManagement; |
| import org.apache.maven.model.Exclusion; |
| import org.apache.maven.model.Extension; |
| import org.apache.maven.model.Model; |
| import org.apache.maven.model.Parent; |
| import org.apache.maven.model.Plugin; |
| import org.apache.maven.model.PluginExecution; |
| import org.apache.maven.model.PluginManagement; |
| import org.apache.maven.model.Profile; |
| import org.apache.maven.model.ReportPlugin; |
| import org.apache.maven.model.Repository; |
| import org.apache.maven.model.Resource; |
| import org.apache.maven.model.io.xpp3.MavenXpp3Reader; |
| import org.apache.maven.profiles.DefaultProfileManager; |
| import org.apache.maven.profiles.MavenProfilesBuilder; |
| import org.apache.maven.profiles.ProfileManager; |
| import org.apache.maven.profiles.ProfilesConversionUtils; |
| import org.apache.maven.profiles.ProfilesRoot; |
| import org.apache.maven.profiles.activation.ProfileActivationException; |
| import org.apache.maven.project.artifact.InvalidDependencyVersionException; |
| import org.apache.maven.project.artifact.ProjectArtifactFactory; |
| import org.apache.maven.project.inheritance.ModelInheritanceAssembler; |
| import org.apache.maven.project.injection.ModelDefaultsInjector; |
| import org.apache.maven.project.injection.ProfileInjector; |
| import org.apache.maven.project.interpolation.ModelInterpolationException; |
| import org.apache.maven.project.interpolation.ModelInterpolator; |
| import org.apache.maven.project.path.PathTranslator; |
| import org.apache.maven.project.validation.ModelValidationResult; |
| import org.apache.maven.project.validation.ModelValidator; |
| import org.apache.maven.wagon.events.TransferListener; |
| import org.codehaus.plexus.PlexusConstants; |
| import org.codehaus.plexus.PlexusContainer; |
| import org.codehaus.plexus.component.repository.exception.ComponentLookupException; |
| import org.codehaus.plexus.context.Context; |
| import org.codehaus.plexus.context.ContextException; |
| import org.codehaus.plexus.logging.AbstractLogEnabled; |
| import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; |
| import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; |
| import org.codehaus.plexus.util.IOUtil; |
| import org.codehaus.plexus.util.ReaderFactory; |
| import org.codehaus.plexus.util.StringUtils; |
| import org.codehaus.plexus.util.xml.pull.XmlPullParserException; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.io.StringReader; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeMap; |
| |
| /*:apt |
| |
| ----- |
| POM lifecycle |
| ----- |
| |
| POM Lifecycle |
| |
| Order of operations when building a POM |
| |
| * inheritance |
| * path translation |
| * interpolation |
| * defaults injection |
| |
| Current processing is: |
| |
| * inheritance |
| * interpolation |
| * defaults injection |
| * path translation |
| |
| I'm not sure how this is working at all ... i think i have a case where this is failing but i need to |
| encapsulate as a test so i can fix it. Also need to think of the in working build directory versus looking |
| things up from the repository i.e buildFromSource vs buildFromRepository. |
| |
| Notes |
| |
| * when the model is read it may not have a groupId, as it must be inherited |
| |
| * the inheritance assembler must use models that are unadulterated! |
| |
| */ |
| |
| /** |
| * @version $Id$ |
| */ |
| public class DefaultMavenProjectBuilder |
| extends AbstractLogEnabled |
| implements MavenProjectBuilder, Initializable, Contextualizable |
| { |
| // TODO: remove |
| private PlexusContainer container; |
| |
| protected MavenProfilesBuilder profilesBuilder; |
| |
| protected ArtifactResolver artifactResolver; |
| |
| protected ArtifactMetadataSource artifactMetadataSource; |
| |
| private ProjectArtifactFactory artifactFactory; |
| |
| private ModelInheritanceAssembler modelInheritanceAssembler; |
| |
| private ProfileInjector profileInjector; |
| |
| private ModelValidator validator; |
| |
| private Map rawProjectCache = new HashMap(); |
| |
| private Map processedProjectCache = new HashMap(); |
| |
| // TODO: make it a component |
| private MavenXpp3Reader modelReader; |
| |
| private PathTranslator pathTranslator; |
| |
| private ModelDefaultsInjector modelDefaultsInjector; |
| |
| private ModelInterpolator modelInterpolator; |
| |
| private ArtifactRepositoryFactory artifactRepositoryFactory; |
| |
| // ---------------------------------------------------------------------- |
| // I am making this available for use with a new method that takes a |
| // a monitor wagon monitor as a parameter so that tools can use the |
| // methods here and receive callbacks. MNG-1015 |
| // ---------------------------------------------------------------------- |
| |
| private WagonManager wagonManager; |
| |
| public static final String MAVEN_MODEL_VERSION = "4.0.0"; |
| |
| public void initialize() |
| { |
| modelReader = new MavenXpp3Reader(); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // MavenProjectBuilder Implementation |
| // ---------------------------------------------------------------------- |
| |
| public MavenProject build( File pom, |
| ProjectBuilderConfiguration config ) |
| throws ProjectBuildingException |
| { |
| return buildFromSourceFileInternal( pom, config, true ); |
| } |
| |
| public MavenProject build( File pom, |
| ProjectBuilderConfiguration config, |
| boolean checkDistributionManagementStatus ) |
| throws ProjectBuildingException |
| { |
| return buildFromSourceFileInternal( pom, config, checkDistributionManagementStatus ); |
| } |
| |
| public MavenProject build( File projectDescriptor, |
| ArtifactRepository localRepository, |
| ProfileManager profileManager ) |
| throws ProjectBuildingException |
| { |
| ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager ); |
| return buildFromSourceFileInternal( projectDescriptor, config, true ); |
| } |
| |
| public MavenProject build( File projectDescriptor, |
| ArtifactRepository localRepository, |
| ProfileManager profileManager, |
| boolean checkDistributionManagementStatus ) |
| throws ProjectBuildingException |
| { |
| ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager ); |
| return buildFromSourceFileInternal( projectDescriptor, config, checkDistributionManagementStatus ); |
| } |
| |
| // jvz:note |
| // When asked for something from the repository are we getting it from the reactor? Yes, when using this call |
| // we are assuming that the reactor has been run and we have collected the projects required to satisfy it0042 |
| // which means the projects in the reactor are required for finding classes in <project>/target/classes. Not |
| // sure this is ideal. I remove all caching from the builder and all reactor related ITs which assume |
| // access to simbling project resources failed. |
| public MavenProject buildFromRepository( Artifact artifact, |
| List remoteArtifactRepositories, |
| ArtifactRepository localRepository, |
| boolean allowStubModel ) |
| throws ProjectBuildingException |
| { |
| ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ); |
| |
| return buildFromRepository( artifact, remoteArtifactRepositories, config, allowStubModel ); |
| } |
| |
| public MavenProject buildFromRepository( Artifact artifact, |
| List remoteArtifactRepositories, |
| ProjectBuilderConfiguration config, |
| boolean allowStubModel ) |
| throws ProjectBuildingException |
| { |
| String cacheKey = createCacheKey( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() ); |
| |
| MavenProject project = (MavenProject) processedProjectCache.get( cacheKey ); |
| |
| if ( project != null ) |
| { |
| return project; |
| } |
| |
| Model model = findModelFromRepository( artifact, remoteArtifactRepositories, config, allowStubModel ); |
| |
| return buildInternal( "Artifact [" + artifact + "]", model, config, remoteArtifactRepositories, |
| null, false ); |
| } |
| |
| public MavenProject buildFromRepository( Artifact artifact, |
| List remoteArtifactRepositories, |
| ArtifactRepository localRepository ) |
| throws ProjectBuildingException |
| { |
| return buildFromRepository( artifact, remoteArtifactRepositories, localRepository, true ); |
| } |
| |
| // what is using this externally? jvz. |
| public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository ) |
| throws ProjectBuildingException |
| { |
| //TODO mkleint - use the (Container, Properties) constructor to make system properties embeddable |
| ProfileManager profileManager = new DefaultProfileManager( container ); |
| |
| return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ) |
| .setGlobalProfileManager( profileManager ) ); |
| } |
| |
| public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository, |
| ProfileManager profileManager ) |
| throws ProjectBuildingException |
| { |
| return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ) |
| .setGlobalProfileManager( profileManager ) ); |
| } |
| |
| public MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration config ) |
| throws ProjectBuildingException |
| { |
| Model superModel = getSuperModel(); |
| |
| superModel.setGroupId( STANDALONE_SUPERPOM_GROUPID ); |
| |
| superModel.setArtifactId( STANDALONE_SUPERPOM_ARTIFACTID ); |
| |
| superModel.setVersion( STANDALONE_SUPERPOM_VERSION ); |
| |
| |
| List activeProfiles; |
| |
| ProfileManager profileManager = config.getGlobalProfileManager(); |
| |
| if ( profileManager == null ) |
| { |
| profileManager = new DefaultProfileManager( container ); |
| } |
| |
| profileManager.addProfiles( superModel.getProfiles() ); |
| |
| String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID ); |
| |
| activeProfiles = injectActiveProfiles( profileManager, superModel ); |
| |
| MavenProject project = new MavenProject( superModel ); |
| |
| project.setManagedVersionMap( |
| createManagedVersionMap( projectId, superModel.getDependencyManagement(), null ) ); |
| |
| project.setActiveProfiles( activeProfiles ); |
| |
| project.setOriginalModel( superModel ); |
| |
| try |
| { |
| project = processProjectLogic( "<Super-POM>", project, config, null, null, true, true ); |
| |
| project.setExecutionRoot( true ); |
| |
| return project; |
| } |
| catch ( ModelInterpolationException e ) |
| { |
| throw new ProjectBuildingException( projectId, e.getMessage(), e ); |
| } |
| catch ( InvalidRepositoryException e ) |
| { |
| throw new ProjectBuildingException( projectId, e.getMessage(), e ); |
| } |
| } |
| |
| public MavenProject buildWithDependencies( File projectDescriptor, |
| ArtifactRepository localRepository, |
| ProfileManager profileManager ) |
| throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException |
| { |
| return buildWithDependencies( projectDescriptor, localRepository, profileManager, null ); |
| } |
| |
| // note:jvz This was added for the embedder. |
| |
| /** @todo move to metadatasource itself? */ |
| public MavenProject buildWithDependencies( File projectDescriptor, |
| ArtifactRepository localRepository, |
| ProfileManager profileManager, |
| TransferListener transferListener ) |
| throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException |
| { |
| MavenProject project = build( projectDescriptor, localRepository, profileManager, false ); |
| |
| // ---------------------------------------------------------------------- |
| // Typically when the project builder is being used from maven proper |
| // the transitive dependencies will not be resolved here because this |
| // requires a lot of work when we may only be interested in running |
| // something simple like 'm2 clean'. So the artifact collector is used |
| // in the dependency resolution phase if it is required by any of the |
| // goals being executed. But when used as a component in another piece |
| // of code people may just want to build maven projects and have the |
| // dependencies resolved for whatever reason: this is why we keep |
| // this snippet of code here. |
| // ---------------------------------------------------------------------- |
| |
| // TODO: such a call in MavenMetadataSource too - packaging not really the intention of type |
| Artifact projectArtifact = project.getArtifact(); |
| |
| String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() ); |
| |
| // Map managedVersions = createManagedVersionMap( projectId, project.getDependencyManagement() ); |
| Map managedVersions = project.getManagedVersionMap(); |
| |
| ensureMetadataSourceIsInitialized(); |
| |
| try |
| { |
| project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) ); |
| } |
| catch ( InvalidDependencyVersionException e ) |
| { |
| throw new ProjectBuildingException( projectId, |
| "Unable to build project due to an invalid dependency version: " + |
| e.getMessage(), e ); |
| } |
| |
| if ( transferListener != null ) |
| { |
| wagonManager.setDownloadMonitor( transferListener ); |
| } |
| |
| ArtifactResolutionResult result = artifactResolver.resolveTransitively( project.getDependencyArtifacts(), |
| projectArtifact, managedVersions, |
| localRepository, |
| project.getRemoteArtifactRepositories(), |
| artifactMetadataSource ); |
| |
| project.setArtifacts( result.getArtifacts() ); |
| |
| return project; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // |
| // ---------------------------------------------------------------------- |
| |
| private void ensureMetadataSourceIsInitialized() |
| throws ProjectBuildingException |
| { |
| if ( artifactMetadataSource == null ) |
| { |
| try |
| { |
| artifactMetadataSource = (ArtifactMetadataSource) container.lookup( ArtifactMetadataSource.ROLE ); |
| } |
| catch ( ComponentLookupException e ) |
| { |
| throw new ProjectBuildingException( "all", "Cannot lookup metadata source for building the project.", |
| e ); |
| } |
| } |
| } |
| |
| private Map createManagedVersionMap( String projectId, |
| DependencyManagement dependencyManagement, |
| MavenProject parent ) |
| throws ProjectBuildingException |
| { |
| Map map = null; |
| List deps; |
| if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null ) && |
| ( deps.size() > 0 ) ) |
| { |
| map = new ManagedVersionMap( map ); |
| |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( "Adding managed dependencies for " + projectId ); |
| } |
| |
| for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); ) |
| { |
| Dependency d = (Dependency) i.next(); |
| |
| try |
| { |
| VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() ); |
| |
| Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), |
| versionRange, d.getType(), |
| d.getClassifier(), d.getScope(), |
| d.isOptional() ); |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( " " + artifact ); |
| } |
| |
| // If the dependencyManagement section listed exclusions, |
| // add them to the managed artifacts here so that transitive |
| // dependencies will be excluded if necessary. |
| if ( ( null != d.getExclusions() ) && !d.getExclusions().isEmpty() ) |
| { |
| List exclusions = new ArrayList(); |
| |
| Iterator exclItr = d.getExclusions().iterator(); |
| |
| while ( exclItr.hasNext() ) |
| { |
| Exclusion e = (Exclusion) exclItr.next(); |
| exclusions.add( e.getGroupId() + ":" + e.getArtifactId() ); |
| } |
| ExcludesArtifactFilter eaf = new ExcludesArtifactFilter( exclusions ); |
| artifact.setDependencyFilter( eaf ); |
| } |
| else |
| { |
| artifact.setDependencyFilter( null ); |
| } |
| map.put( d.getManagementKey(), artifact ); |
| } |
| catch ( InvalidVersionSpecificationException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Unable to parse version '" + d.getVersion() + |
| "' for dependency '" + d.getManagementKey() + "': " + e.getMessage(), e ); |
| } |
| } |
| } |
| else if ( map == null ) |
| { |
| map = Collections.EMPTY_MAP; |
| } |
| |
| return map; |
| } |
| |
| private MavenProject buildFromSourceFileInternal( File projectDescriptor, |
| ProjectBuilderConfiguration config, |
| boolean checkDistributionManagementStatus ) |
| throws ProjectBuildingException |
| { |
| Model model = readModel( "unknown", projectDescriptor, true ); |
| |
| MavenProject project = buildInternal( projectDescriptor.getAbsolutePath(), model, config, |
| buildArtifactRepositories( getSuperModel() ), projectDescriptor, |
| true ); |
| |
| if ( checkDistributionManagementStatus ) |
| { |
| if ( ( project.getDistributionManagement() != null ) && |
| ( project.getDistributionManagement().getStatus() != null ) ) |
| { |
| String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() ); |
| |
| throw new ProjectBuildingException( projectId, |
| "Invalid project file: distribution status must not be specified for a project outside of the repository" ); |
| } |
| } |
| |
| return project; |
| } |
| |
| private Model findModelFromRepository( Artifact artifact, |
| List remoteArtifactRepositories, |
| ProjectBuilderConfiguration config, |
| boolean allowStubModel ) |
| throws ProjectBuildingException |
| { |
| String projectId = safeVersionlessKey( artifact.getGroupId(), artifact.getArtifactId() ); |
| |
| normalizeToArtifactRepositories( remoteArtifactRepositories, projectId ); |
| |
| Artifact projectArtifact; |
| |
| // if the artifact is not a POM, we need to construct a POM artifact based on the artifact parameter given. |
| if ( "pom".equals( artifact.getType() ) ) |
| { |
| projectArtifact = artifact; |
| } |
| else |
| { |
| getLogger().debug( "Attempting to build MavenProject instance for Artifact (" + artifact.getGroupId() + ":" |
| + artifact.getArtifactId() + ":" + artifact.getVersion() + ") of type: " |
| + artifact.getType() + "; constructing POM artifact instead." ); |
| |
| projectArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(), |
| artifact.getVersion(), artifact.getScope() ); |
| } |
| |
| Model model; |
| |
| try |
| { |
| artifactResolver.resolve( projectArtifact, remoteArtifactRepositories, config.getLocalRepository() ); |
| |
| File file = projectArtifact.getFile(); |
| |
| model = readModel( projectId, file, false ); |
| |
| String downloadUrl = null; |
| |
| ArtifactStatus status = ArtifactStatus.NONE; |
| |
| DistributionManagement distributionManagement = model.getDistributionManagement(); |
| |
| if ( distributionManagement != null ) |
| { |
| downloadUrl = distributionManagement.getDownloadUrl(); |
| |
| status = ArtifactStatus.valueOf( distributionManagement.getStatus() ); |
| } |
| |
| checkStatusAndUpdate( projectArtifact, status, file, remoteArtifactRepositories, config.getLocalRepository() ); |
| |
| // TODO: this is gross. Would like to give it the whole model, but maven-artifact shouldn't depend on that |
| // Can a maven-core implementation of the Artifact interface store it, and be used in the exceptions? |
| if ( downloadUrl != null ) |
| { |
| projectArtifact.setDownloadUrl( downloadUrl ); |
| } |
| else |
| { |
| projectArtifact.setDownloadUrl( model.getUrl() ); |
| } |
| } |
| catch ( ArtifactResolutionException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Error getting POM for '" + projectId + |
| "' from the repository: " + e.getMessage(), e ); |
| } |
| catch ( ArtifactNotFoundException e ) |
| { |
| if ( allowStubModel ) |
| { |
| getLogger().debug( "Artifact not found - using stub model: " + e.getMessage() ); |
| |
| model = createStubModel( projectArtifact ); |
| } |
| else |
| { |
| throw new ProjectBuildingException( projectId, "POM '" + projectId + "' not found in repository: " + |
| e.getMessage(), e ); |
| } |
| } |
| |
| return model; |
| } |
| |
| private List normalizeToArtifactRepositories( List remoteArtifactRepositories, |
| String projectId ) |
| throws ProjectBuildingException |
| { |
| List normalized = new ArrayList( remoteArtifactRepositories.size() ); |
| |
| boolean normalizationNeeded = false; |
| for ( Iterator it = remoteArtifactRepositories.iterator(); it.hasNext(); ) |
| { |
| Object item = it.next(); |
| |
| if ( item instanceof ArtifactRepository ) |
| { |
| normalized.add( item ); |
| } |
| else if ( item instanceof Repository ) |
| { |
| Repository repo = (Repository) item; |
| try |
| { |
| item = ProjectUtils.buildArtifactRepository( repo, artifactRepositoryFactory, container ); |
| |
| normalized.add( item ); |
| normalizationNeeded = true; |
| } |
| catch ( InvalidRepositoryException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Error building artifact repository for id: " + repo.getId(), e ); |
| } |
| } |
| else |
| { |
| throw new ProjectBuildingException( projectId, "Error building artifact repository from non-repository information item: " + item ); |
| } |
| } |
| |
| if ( normalizationNeeded ) |
| { |
| return normalized; |
| } |
| else |
| { |
| return remoteArtifactRepositories; |
| } |
| } |
| |
| private void checkStatusAndUpdate( Artifact projectArtifact, |
| ArtifactStatus status, |
| File file, |
| List remoteArtifactRepositories, |
| ArtifactRepository localRepository ) |
| throws ArtifactNotFoundException |
| { |
| // TODO: configurable actions dependant on status |
| if ( !projectArtifact.isSnapshot() && ( status.compareTo( ArtifactStatus.DEPLOYED ) < 0 ) ) |
| { |
| // use default policy (enabled, daily update, warn on bad checksum) |
| ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy(); |
| // TODO: re-enable [MNG-798/865] |
| policy.setUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER ); |
| |
| if ( policy.checkOutOfDate( new Date( file.lastModified() ) ) ) |
| { |
| getLogger().info( |
| projectArtifact.getArtifactId() + ": updating metadata due to status of '" + status + "'" ); |
| try |
| { |
| projectArtifact.setResolved( false ); |
| artifactResolver.resolveAlways( projectArtifact, remoteArtifactRepositories, localRepository ); |
| } |
| catch ( ArtifactResolutionException e ) |
| { |
| getLogger().warn( "Error updating POM - using existing version" ); |
| getLogger().debug( "Cause", e ); |
| } |
| catch ( ArtifactNotFoundException e ) |
| { |
| getLogger().warn( "Error updating POM - not found. Removing local copy." ); |
| getLogger().debug( "Cause", e ); |
| file.delete(); |
| throw e; |
| } |
| } |
| } |
| } |
| |
| // jvz:note |
| // This is used when requested artifacts do not have an associated POM. This is for the case where we are |
| // using an m1 repo where the only thing required to be present are the JAR files. |
| private Model createStubModel( Artifact projectArtifact ) |
| { |
| getLogger().debug( "Using defaults for missing POM " + 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( ArtifactStatus.GENERATED.toString() ); |
| |
| return model; |
| } |
| |
| // jvz:note |
| // We've got a mixture of things going in the USD and from the repository, sometimes the descriptor |
| // is a real file and sometimes null which makes things confusing. |
| private MavenProject buildInternal( String pomLocation, |
| Model model, |
| ProjectBuilderConfiguration config, |
| List parentSearchRepositories, |
| File projectDescriptor, |
| boolean strict ) |
| throws ProjectBuildingException |
| { |
| File projectDir = null; |
| |
| if ( projectDescriptor != null ) |
| { |
| projectDir = projectDescriptor.getAbsoluteFile().getParentFile(); |
| } |
| |
| Model superModel = getSuperModel(); |
| |
| ProfileManager externalProfileManager = config.getGlobalProfileManager(); |
| ProfileManager superProjectProfileManager; |
| if ( externalProfileManager != null ) |
| { |
| superProjectProfileManager = new DefaultProfileManager( |
| container, |
| externalProfileManager.getRequestProperties() ); |
| } |
| else |
| { |
| superProjectProfileManager = new DefaultProfileManager( container ); |
| } |
| |
| List activeProfiles; |
| |
| superProjectProfileManager.addProfiles( superModel.getProfiles() ); |
| |
| activeProfiles = injectActiveProfiles( superProjectProfileManager, superModel ); |
| |
| MavenProject superProject = new MavenProject( superModel ); |
| |
| superProject.setActiveProfiles( activeProfiles ); |
| |
| //noinspection CollectionDeclaredAsConcreteClass |
| LinkedList lineage = new LinkedList(); |
| |
| // TODO: the aRWR can get out of sync with project.model.repositories. We should do all the processing of |
| // profiles, etc on the models then recreate the aggregated sets at the end from the project repositories (they |
| // must still be created along the way so that parent poms can be discovered, however) |
| // Use a TreeSet to ensure ordering is retained |
| Set aggregatedRemoteWagonRepositories = new LinkedHashSet(); |
| |
| String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); |
| |
| List activeExternalProfiles; |
| try |
| { |
| if ( externalProfileManager != null ) |
| { |
| activeExternalProfiles = externalProfileManager.getActiveProfiles(); |
| } |
| else |
| { |
| activeExternalProfiles = Collections.EMPTY_LIST; |
| } |
| } |
| catch ( ProfileActivationException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Failed to calculate active external profiles.", e ); |
| } |
| |
| for ( Iterator i = activeExternalProfiles.iterator(); i.hasNext(); ) |
| { |
| Profile externalProfile = (Profile) i.next(); |
| |
| for ( Iterator repoIterator = externalProfile.getRepositories().iterator(); repoIterator.hasNext(); ) |
| { |
| Repository mavenRepo = (Repository) repoIterator.next(); |
| |
| ArtifactRepository artifactRepo = null; |
| try |
| { |
| artifactRepo = |
| ProjectUtils.buildArtifactRepository( mavenRepo, artifactRepositoryFactory, container ); |
| } |
| catch ( InvalidRepositoryException e ) |
| { |
| throw new ProjectBuildingException( projectId, e.getMessage(), e ); |
| } |
| |
| aggregatedRemoteWagonRepositories.add( artifactRepo ); |
| } |
| } |
| |
| MavenProject project = null; |
| try |
| { |
| project = assembleLineage( model, lineage, config, projectDescriptor, parentSearchRepositories, |
| aggregatedRemoteWagonRepositories, strict ); |
| } |
| catch ( InvalidRepositoryException e ) |
| { |
| throw new ProjectBuildingException( projectId, e.getMessage(), e ); |
| } |
| |
| // 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(); |
| |
| for ( Iterator i = lineage.iterator(); i.hasNext(); ) |
| { |
| MavenProject currentProject = (MavenProject) i.next(); |
| |
| Model current = currentProject.getModel(); |
| |
| String pathAdjustment = null; |
| |
| try |
| { |
| pathAdjustment = previousProject.getModulePathAdjustment( currentProject ); |
| } |
| catch ( IOException e ) |
| { |
| getLogger().debug( "Cannot determine whether " + currentProject.getId() + " is a module of " + |
| previousProject.getId() + ". Reason: " + e.getMessage(), e ); |
| } |
| |
| modelInheritanceAssembler.assembleModelInheritance( current, previous, pathAdjustment ); |
| |
| previous = current; |
| previousProject = currentProject; |
| } |
| |
| // only add the super repository if it wasn't overridden by a profile or project |
| List repositories = new ArrayList( aggregatedRemoteWagonRepositories ); |
| repositories.addAll( parentSearchRepositories ); |
| |
| List superRepositories = buildArtifactRepositories( superModel ); |
| |
| for ( Iterator i = superRepositories.iterator(); i.hasNext(); ) |
| { |
| ArtifactRepository repository = (ArtifactRepository) i.next(); |
| |
| if ( !repositories.contains( repository ) ) |
| { |
| repositories.add( repository ); |
| } |
| } |
| |
| // merge any duplicated plugin definitions together, using the first appearance as the dominant one. |
| ModelUtils.mergeDuplicatePluginDefinitions( project.getModel().getBuild() ); |
| |
| try |
| { |
| project = processProjectLogic( pomLocation, project, config, projectDir, repositories, strict, false ); |
| } |
| catch ( ModelInterpolationException e ) |
| { |
| throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e ); |
| } |
| catch ( InvalidRepositoryException e ) |
| { |
| throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e ); |
| } |
| |
| processedProjectCache.put( |
| createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project ); |
| |
| // jvz:note |
| // this only happens if we are building from a source file |
| if ( projectDescriptor != null ) |
| { |
| Build build = project.getBuild(); |
| |
| project.addCompileSourceRoot( build.getSourceDirectory() ); |
| |
| project.addScriptSourceRoot( build.getScriptSourceDirectory() ); |
| |
| project.addTestCompileSourceRoot( build.getTestSourceDirectory() ); |
| |
| // Only track the file of a POM in the source tree |
| project.setFile( projectDescriptor ); |
| } |
| |
| project.setManagedVersionMap( createManagedVersionMap( projectId, |
| project.getDependencyManagement(), |
| project.getParent() ) ); |
| |
| return project; |
| } |
| |
| private String safeVersionlessKey( String groupId, |
| String artifactId ) |
| { |
| String gid = groupId; |
| |
| if ( StringUtils.isEmpty( gid ) ) |
| { |
| gid = "unknown"; |
| } |
| |
| String aid = artifactId; |
| |
| if ( StringUtils.isEmpty( aid ) ) |
| { |
| aid = "unknown"; |
| } |
| |
| return ArtifactUtils.versionlessKey( gid, aid ); |
| } |
| |
| private List buildArtifactRepositories( Model model ) |
| throws ProjectBuildingException |
| { |
| try |
| { |
| return ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory, |
| container ); |
| } |
| catch ( InvalidRepositoryException e ) |
| { |
| String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); |
| |
| throw new ProjectBuildingException( projectId, e.getMessage(), e ); |
| } |
| } |
| |
| /** |
| * @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 MavenProject processProjectLogic( String pomLocation, |
| MavenProject project, |
| ProjectBuilderConfiguration config, |
| File projectDir, |
| List remoteRepositories, |
| boolean strict, |
| boolean isSuperPom ) |
| throws ProjectBuildingException, ModelInterpolationException, InvalidRepositoryException |
| { |
| Model model = project.getModel(); |
| |
| List activeProfiles = project.getActiveProfiles(); |
| |
| if ( activeProfiles == null ) |
| { |
| activeProfiles = new ArrayList(); |
| } |
| |
| ProfileManager profileMgr = config == null ? null : config.getGlobalProfileManager(); |
| |
| List injectedProfiles = injectActiveProfiles( profileMgr, model ); |
| |
| activeProfiles.addAll( injectedProfiles ); |
| |
| // -------------------------------------------------------------------------------- |
| |
| Build dynamicBuild = model.getBuild(); |
| |
| model.setBuild( ModelUtils.cloneBuild( dynamicBuild ) ); |
| |
| model = modelInterpolator.interpolate( model, projectDir, config, getLogger().isDebugEnabled() ); |
| |
| mergeDeterministicBuildElements( model.getBuild(), dynamicBuild ); |
| |
| model.setBuild( dynamicBuild ); |
| |
| // MNG-3482: Make sure depMgmt is interpolated before merging. |
| if ( !isSuperPom ) |
| { |
| mergeManagedDependencies( model, config, remoteRepositories ); |
| } |
| |
| // interpolation is before injection, because interpolation is off-limits in the injected variables |
| modelDefaultsInjector.injectDefaults( model ); |
| |
| MavenProject parentProject = project.getParent(); |
| |
| Model originalModel = project.getOriginalModel(); |
| |
| // We will return a different project object using the new model (hence the need to return a project, not just modify the parameter) |
| project = new MavenProject( model, getLogger() ); |
| |
| project.setOriginalModel( originalModel ); |
| |
| project.setActiveProfiles( activeProfiles ); |
| |
| // 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.create( project ); |
| |
| project.setArtifact( projectArtifact ); |
| project.setProjectBuilderConfiguration( config ); |
| |
| project.setPluginArtifactRepositories( ProjectUtils.buildArtifactRepositories( model.getPluginRepositories(), |
| artifactRepositoryFactory, |
| container ) ); |
| |
| DistributionManagement dm = model.getDistributionManagement(); |
| if ( dm != null ) |
| { |
| ArtifactRepository repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getRepository(), |
| artifactRepositoryFactory, |
| container ); |
| project.setReleaseArtifactRepository( repo ); |
| |
| if ( dm.getSnapshotRepository() != null ) |
| { |
| repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getSnapshotRepository(), |
| artifactRepositoryFactory, container ); |
| project.setSnapshotArtifactRepository( repo ); |
| } |
| } |
| |
| if ( parentProject != null ) |
| { |
| String cacheKey = createCacheKey( parentProject.getGroupId(), |
| parentProject.getArtifactId(), |
| parentProject.getVersion() ); |
| |
| MavenProject processedParent = (MavenProject) processedProjectCache.get( cacheKey ); |
| Artifact parentArtifact; |
| |
| // yeah, this null check might be a bit paranoid, but better safe than sorry... |
| if ( processedParent != null ) |
| { |
| project.setParent( processedParent ); |
| |
| parentArtifact = processedParent.getArtifact(); |
| } |
| else |
| { |
| project.setParent( parentProject ); |
| |
| 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 ); |
| |
| String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); |
| |
| if ( validationResult.getMessageCount() > 0 ) |
| { |
| throw new InvalidProjectModelException( projectId, pomLocation, "Failed to validate POM", |
| validationResult ); |
| } |
| |
| project.setRemoteArtifactRepositories( |
| ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory, container ) ); |
| |
| // TODO: these aren't taking active project artifacts into consideration in the reactor |
| project.setPluginArtifacts( createPluginArtifacts( projectId, project.getBuildPlugins() ) ); |
| |
| project.setReportArtifacts( createReportArtifacts( projectId, project.getReportPlugins() ) ); |
| |
| project.setExtensionArtifacts( createExtensionArtifacts( projectId, project.getBuildExtensions() ) ); |
| |
| return project; |
| } |
| |
| private void mergeDeterministicBuildElements( Build interpolatedBuild, |
| Build dynamicBuild ) |
| { |
| mergeDeterministicPluginElements( interpolatedBuild.getPlugins(), dynamicBuild.getPlugins() ); |
| |
| PluginManagement dPluginMgmt = dynamicBuild.getPluginManagement(); |
| PluginManagement iPluginMgmt = interpolatedBuild.getPluginManagement(); |
| |
| if ( dPluginMgmt != null ) |
| { |
| mergeDeterministicPluginElements( iPluginMgmt.getPlugins(), dPluginMgmt.getPlugins() ); |
| } |
| |
| if ( dynamicBuild.getExtensions() != null ) |
| { |
| dynamicBuild.setExtensions( interpolatedBuild.getExtensions() ); |
| } |
| } |
| |
| private void mergeDeterministicPluginElements( List iPlugins, List dPlugins ) |
| { |
| if ( dPlugins != null ) |
| { |
| for ( int i = 0; i < dPlugins.size(); i++ ) |
| { |
| Plugin dPlugin = (Plugin) dPlugins.get( i ); |
| Plugin iPlugin = (Plugin) iPlugins.get( i ); |
| |
| dPlugin.setGroupId( iPlugin.getGroupId() ); |
| dPlugin.setArtifactId( iPlugin.getArtifactId() ); |
| dPlugin.setVersion( iPlugin.getVersion() ); |
| |
| dPlugin.setDependencies( iPlugin.getDependencies() ); |
| |
| List dExecutions = dPlugin.getExecutions(); |
| if ( dExecutions != null ) |
| { |
| List iExecutions = iPlugin.getExecutions(); |
| |
| for ( int j = 0; j < dExecutions.size(); j++ ) |
| { |
| PluginExecution dExec = (PluginExecution) dExecutions.get( j ); |
| PluginExecution iExec = (PluginExecution) iExecutions.get( j ); |
| |
| dExec.setId( iExec.getId() ); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * @noinspection CollectionDeclaredAsConcreteClass |
| * @todo We need to find an effective way to unit test parts of this method! |
| * @todo Refactor this into smaller methods with discrete purposes. |
| */ |
| private MavenProject assembleLineage( Model model, |
| LinkedList lineage, |
| ProjectBuilderConfiguration config, |
| File projectDescriptor, |
| List parentSearchRepositories, |
| Set aggregatedRemoteWagonRepositories, |
| boolean strict ) |
| throws ProjectBuildingException, InvalidRepositoryException |
| { |
| Model originalModel = ModelUtils.cloneModel( model ); |
| |
| File projectDir = null; |
| if ( projectDescriptor != null ) |
| { |
| projectDir = projectDescriptor.getAbsoluteFile().getParentFile(); |
| } |
| |
| ProfileManager externalProfileManager = config.getGlobalProfileManager(); |
| ProfileManager profileManager; |
| if ( externalProfileManager != null ) |
| { |
| profileManager = new DefaultProfileManager( container, externalProfileManager.getRequestProperties() ); |
| } |
| else |
| { |
| //TODO mkleint - use the (Container, Properties constructor to make system properties embeddable |
| profileManager = new DefaultProfileManager( container ); |
| } |
| |
| if ( externalProfileManager != null ) |
| { |
| profileManager.explicitlyActivate( externalProfileManager.getExplicitlyActivatedIds() ); |
| |
| profileManager.explicitlyDeactivate( externalProfileManager.getExplicitlyDeactivatedIds() ); |
| } |
| |
| List activeProfiles; |
| |
| try |
| { |
| profileManager.addProfiles( model.getProfiles() ); |
| |
| loadProjectExternalProfiles( profileManager, projectDir ); |
| |
| activeProfiles = injectActiveProfiles( profileManager, model ); |
| } |
| catch ( ProfileActivationException e ) |
| { |
| String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); |
| |
| throw new ProjectBuildingException( projectId, "Failed to activate local (project-level) build profiles: " + |
| e.getMessage(), e ); |
| } |
| |
| if ( !model.getRepositories().isEmpty() ) |
| { |
| List respositories = buildArtifactRepositories( model ); |
| |
| for ( Iterator it = respositories.iterator(); it.hasNext(); ) |
| { |
| ArtifactRepository repository = (ArtifactRepository) it.next(); |
| |
| if ( !aggregatedRemoteWagonRepositories.contains( repository ) ) |
| { |
| aggregatedRemoteWagonRepositories.add( repository ); |
| } |
| } |
| } |
| |
| MavenProject project = new MavenProject( model, getLogger() ); |
| |
| project.setFile( projectDescriptor ); |
| project.setActiveProfiles( activeProfiles ); |
| project.setOriginalModel( originalModel ); |
| |
| lineage.addFirst( project ); |
| |
| Parent parentModel = model.getParent(); |
| |
| String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); |
| |
| if ( parentModel != null ) |
| { |
| if ( StringUtils.isEmpty( parentModel.getGroupId() ) ) |
| { |
| throw new ProjectBuildingException( projectId, "Missing groupId element from parent element" ); |
| } |
| 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; |
| |
| String parentKey = |
| createCacheKey( parentModel.getGroupId(), parentModel.getArtifactId(), parentModel.getVersion() ); |
| MavenProject parentProject = (MavenProject) rawProjectCache.get( parentKey ); |
| |
| if ( parentProject != null ) |
| { |
| model = ModelUtils.cloneModel( parentProject.getOriginalModel() ); |
| |
| parentDescriptor = parentProject.getFile(); |
| } |
| |
| String parentRelativePath = parentModel.getRelativePath(); |
| |
| // if we can't find a cached model matching the parent spec, then let's try to look on disk using |
| // <relativePath/> |
| if ( ( model == null ) && ( projectDir != null ) && StringUtils.isNotEmpty( parentRelativePath ) ) |
| { |
| parentDescriptor = new File( projectDir, parentRelativePath ); |
| |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( "Searching for parent-POM: " + parentModel.getId() + " of project: " + |
| project.getId() + " in relative path: " + parentRelativePath ); |
| } |
| |
| if ( parentDescriptor.isDirectory() ) |
| { |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( "Path specified in <relativePath/> (" + parentRelativePath + |
| ") is a directory. Searching for 'pom.xml' within this directory." ); |
| } |
| |
| parentDescriptor = new File( parentDescriptor, "pom.xml" ); |
| |
| if ( !parentDescriptor.exists() ) |
| { |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( "Parent-POM: " + parentModel.getId() + " for project: " + |
| project.getId() + " cannot be loaded from relative path: " + parentDescriptor + |
| "; path does not exist." ); |
| } |
| } |
| } |
| |
| if ( parentDescriptor != null ) |
| { |
| try |
| { |
| parentDescriptor = parentDescriptor.getCanonicalFile(); |
| } |
| catch ( IOException e ) |
| { |
| getLogger().debug( "Failed to canonicalize potential parent POM: \'" + parentDescriptor + "\'", |
| e ); |
| |
| parentDescriptor = null; |
| } |
| } |
| |
| if ( ( parentDescriptor != null ) && parentDescriptor.exists() ) |
| { |
| Model candidateParent = readModel( projectId, parentDescriptor, strict ); |
| |
| String candidateParentGroupId = candidateParent.getGroupId(); |
| if ( ( candidateParentGroupId == null ) && ( candidateParent.getParent() != null ) ) |
| { |
| candidateParentGroupId = candidateParent.getParent().getGroupId(); |
| } |
| |
| String candidateParentVersion = candidateParent.getVersion(); |
| if ( ( candidateParentVersion == null ) && ( candidateParent.getParent() != null ) ) |
| { |
| candidateParentVersion = candidateParent.getParent().getVersion(); |
| } |
| |
| if ( parentModel.getGroupId().equals( candidateParentGroupId ) && |
| parentModel.getArtifactId().equals( candidateParent.getArtifactId() ) && |
| parentModel.getVersion().equals( candidateParentVersion ) ) |
| { |
| model = candidateParent; |
| |
| getLogger().debug( "Using parent-POM from the project hierarchy at: \'" + |
| parentModel.getRelativePath() + "\' for project: " + project.getId() ); |
| } |
| else |
| { |
| getLogger().debug( "Invalid parent-POM referenced by relative path '" + |
| parentModel.getRelativePath() + "' in parent specification in " + project.getId() + ":" + |
| "\n Specified: " + parentModel.getId() + "\n Found: " + candidateParent.getId() ); |
| } |
| } |
| else if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( |
| "Parent-POM: " + parentModel.getId() + " not found in relative path: " + parentRelativePath ); |
| } |
| } |
| |
| Artifact parentArtifact = null; |
| |
| // only resolve the parent model from the repository system if we didn't find it on disk... |
| if ( model == null ) |
| { |
| // 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; |
| |
| //!! (**) |
| // ---------------------------------------------------------------------- |
| // Do we have the necessary information to actually find the parent |
| // POMs here?? I don't think so ... Say only one remote repository is |
| // specified and that is ibiblio then this model that we just read doesn't |
| // have any repository information ... I think we might have to inherit |
| // as we go in order to do this. |
| // ---------------------------------------------------------------------- |
| |
| // we must add the repository this POM was found in too, by chance it may be located where the parent is |
| // we can't query the parent to ask where it is :) |
| List remoteRepositories = new ArrayList( aggregatedRemoteWagonRepositories ); |
| remoteRepositories.addAll( parentSearchRepositories ); |
| |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( "Retrieving parent-POM: " + parentModel.getId() + " for project: " + |
| project.getId() + " from the repository." ); |
| } |
| |
| parentArtifact = artifactFactory.createParentArtifact( parentModel.getGroupId(), |
| parentModel.getArtifactId(), |
| parentModel.getVersion() ); |
| |
| try |
| { |
| model = findModelFromRepository( parentArtifact, remoteRepositories, config, false ); |
| } |
| catch ( ProjectBuildingException e ) |
| { |
| throw new ProjectBuildingException( project.getId(), "Cannot find parent: " + e.getProjectId() + |
| " for project: " + project.getId(), e ); |
| } |
| } |
| |
| if ( ( model != null ) && !"pom".equals( model.getPackaging() ) ) |
| { |
| throw new ProjectBuildingException( projectId, "Parent: " + model.getId() + " of project: " + |
| projectId + " has wrong packaging: " + model.getPackaging() + ". Must be 'pom'." ); |
| } |
| |
| MavenProject parent = assembleLineage( model, |
| lineage, |
| config, |
| parentDescriptor, |
| parentSearchRepositories, |
| aggregatedRemoteWagonRepositories, |
| strict ); |
| |
| project.setParent( parent ); |
| |
| project.setParentArtifact( parentArtifact ); |
| } |
| |
| rawProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), new MavenProject( project ) ); |
| |
| return project; |
| } |
| |
| private void mergeManagedDependencies(Model model, ProjectBuilderConfiguration config, List parentSearchRepositories) |
| throws ProjectBuildingException |
| { |
| DependencyManagement modelDepMgmt = model.getDependencyManagement(); |
| |
| if (modelDepMgmt != null) |
| { |
| Map depsMap = new TreeMap(); |
| Iterator iter = modelDepMgmt.getDependencies().iterator(); |
| boolean doInclude = false; |
| while (iter.hasNext()) |
| { |
| Dependency dep = (Dependency) iter.next(); |
| depsMap.put( dep.getManagementKey(), dep ); |
| if ( dep.getType().equals( "pom" ) && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) ) |
| { |
| doInclude = true; |
| } |
| } |
| Map newDeps = new TreeMap(depsMap); |
| iter = modelDepMgmt.getDependencies().iterator(); |
| if (doInclude) |
| { |
| while (iter.hasNext()) |
| { |
| Dependency dep = (Dependency)iter.next(); |
| if ( dep.getType().equals( "pom" ) |
| && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) ) |
| { |
| Artifact artifact = artifactFactory.createProjectArtifact( dep.getGroupId(), dep.getArtifactId(), |
| dep.getVersion(), dep.getScope() ); |
| MavenProject project = buildFromRepository(artifact, parentSearchRepositories, config, false); |
| |
| DependencyManagement depMgmt = project.getDependencyManagement(); |
| |
| if (depMgmt != null) |
| { |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( "Importing managed dependencies for " + dep.toString() ); |
| } |
| |
| for ( Iterator it = depMgmt.getDependencies().iterator(); it.hasNext(); ) |
| { |
| Dependency includedDep = (Dependency) it.next(); |
| String key = includedDep.getManagementKey(); |
| if (!newDeps.containsKey(key)) |
| { |
| newDeps.put( includedDep.getManagementKey(), includedDep ); |
| } |
| } |
| newDeps.remove(dep.getManagementKey()); |
| } |
| } |
| } |
| List deps = new ArrayList(newDeps.values()); |
| modelDepMgmt.setDependencies(deps); |
| } |
| } |
| } |
| |
| private List injectActiveProfiles( ProfileManager profileManager, |
| Model model ) |
| throws ProjectBuildingException |
| { |
| List activeProfiles; |
| |
| if ( profileManager != null ) |
| { |
| try |
| { |
| activeProfiles = profileManager.getActiveProfiles(); |
| } |
| catch ( ProfileActivationException e ) |
| { |
| String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); |
| |
| throw new ProjectBuildingException( projectId, e.getMessage(), e ); |
| } |
| |
| for ( Iterator it = activeProfiles.iterator(); it.hasNext(); ) |
| { |
| Profile profile = (Profile) it.next(); |
| |
| profileInjector.inject( profile, model ); |
| } |
| } |
| else |
| { |
| activeProfiles = Collections.EMPTY_LIST; |
| } |
| |
| return activeProfiles; |
| } |
| |
| private void loadProjectExternalProfiles( ProfileManager profileManager, |
| File projectDir ) |
| throws ProfileActivationException |
| { |
| if ( projectDir != null ) |
| { |
| try |
| { |
| ProfilesRoot root = profilesBuilder.buildProfiles( projectDir ); |
| |
| if ( root != null ) |
| { |
| List active = root.getActiveProfiles(); |
| |
| if ( ( active != null ) && !active.isEmpty() ) |
| { |
| profileManager.explicitlyActivate( root.getActiveProfiles() ); |
| } |
| |
| for ( Iterator it = root.getProfiles().iterator(); it.hasNext(); ) |
| { |
| org.apache.maven.profiles.Profile rawProfile = (org.apache.maven.profiles.Profile) it.next(); |
| |
| Profile converted = ProfilesConversionUtils.convertFromProfileXmlProfile( rawProfile ); |
| |
| profileManager.addProfile( converted ); |
| } |
| } |
| } |
| catch ( IOException e ) |
| { |
| throw new ProfileActivationException( "Cannot read profiles.xml resource from directory: " + projectDir, |
| e ); |
| } |
| catch ( XmlPullParserException e ) |
| { |
| throw new ProfileActivationException( |
| "Cannot parse profiles.xml resource from directory: " + projectDir, e ); |
| } |
| } |
| } |
| |
| private Model readModel( String projectId, |
| File file, |
| boolean strict ) |
| throws ProjectBuildingException |
| { |
| Reader reader = null; |
| try |
| { |
| reader = ReaderFactory.newXmlReader( file ); |
| return readModel( projectId, file.getAbsolutePath(), reader, strict ); |
| } |
| catch ( FileNotFoundException e ) |
| { |
| throw new ProjectBuildingException( projectId, |
| "Could not find the model file '" + file.getAbsolutePath() + "'.", e ); |
| } |
| catch ( IOException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Failed to build model from file '" + |
| file.getAbsolutePath() + "'.\nError: \'" + e.getLocalizedMessage() + "\'", e ); |
| } |
| finally |
| { |
| IOUtil.close( reader ); |
| } |
| } |
| |
| private Model readModel( String projectId, |
| String pomLocation, |
| Reader reader, |
| boolean strict ) |
| throws IOException, InvalidProjectModelException |
| { |
| String modelSource = IOUtil.toString( reader ); |
| |
| if ( modelSource.indexOf( "<modelVersion>" + MAVEN_MODEL_VERSION ) < 0 ) |
| { |
| throw new InvalidProjectModelException( projectId, pomLocation, "Not a v" + MAVEN_MODEL_VERSION + " POM." ); |
| } |
| |
| StringReader sReader = new StringReader( modelSource ); |
| |
| try |
| { |
| return modelReader.read( sReader, strict ); |
| } |
| catch ( XmlPullParserException e ) |
| { |
| throw new InvalidProjectModelException( projectId, pomLocation, |
| "Parse error reading POM. Reason: " + e.getMessage(), e ); |
| } |
| } |
| |
| private Model readModel( String projectId, |
| URL url, |
| boolean strict ) |
| throws ProjectBuildingException |
| { |
| Reader reader = null; |
| try |
| { |
| reader = ReaderFactory.newXmlReader( url.openStream() ); |
| return readModel( projectId, url.toExternalForm(), reader, strict ); |
| } |
| catch ( IOException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Failed build model from URL \'" + url.toExternalForm() + |
| "\'\nError: \'" + e.getLocalizedMessage() + "\'", e ); |
| } |
| finally |
| { |
| IOUtil.close( reader ); |
| } |
| } |
| |
| private static String createCacheKey( String groupId, |
| String artifactId, |
| String version ) |
| { |
| return groupId + ":" + artifactId + ":" + version; |
| } |
| |
| protected Set createPluginArtifacts( String projectId, |
| List plugins ) |
| throws ProjectBuildingException |
| { |
| Set pluginArtifacts = new LinkedHashSet(); |
| |
| for ( Iterator i = plugins.iterator(); i.hasNext(); ) |
| { |
| Plugin p = (Plugin) i.next(); |
| |
| String version; |
| if ( StringUtils.isEmpty( p.getVersion() ) ) |
| { |
| version = "RELEASE"; |
| } |
| else |
| { |
| version = p.getVersion(); |
| } |
| |
| Artifact artifact; |
| try |
| { |
| artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(), |
| VersionRange.createFromVersionSpec( version ) ); |
| } |
| catch ( InvalidVersionSpecificationException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Unable to parse version '" + version + |
| "' for plugin '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " + |
| e.getMessage(), e ); |
| } |
| |
| if ( artifact != null ) |
| { |
| pluginArtifacts.add( artifact ); |
| } |
| } |
| |
| return pluginArtifacts; |
| } |
| |
| // TODO: share with createPluginArtifacts? |
| protected Set createReportArtifacts( String projectId, |
| List reports ) |
| throws ProjectBuildingException |
| { |
| Set pluginArtifacts = new LinkedHashSet(); |
| |
| if ( reports != null ) |
| { |
| for ( Iterator i = reports.iterator(); i.hasNext(); ) |
| { |
| ReportPlugin p = (ReportPlugin) i.next(); |
| |
| String version; |
| if ( StringUtils.isEmpty( p.getVersion() ) ) |
| { |
| version = "RELEASE"; |
| } |
| else |
| { |
| version = p.getVersion(); |
| } |
| |
| Artifact artifact; |
| try |
| { |
| artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(), |
| VersionRange.createFromVersionSpec( version ) ); |
| } |
| catch ( InvalidVersionSpecificationException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Unable to parse version '" + version + |
| "' for report '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " + |
| e.getMessage(), e ); |
| } |
| |
| if ( artifact != null ) |
| { |
| pluginArtifacts.add( artifact ); |
| } |
| } |
| } |
| |
| return pluginArtifacts; |
| } |
| |
| // TODO: share with createPluginArtifacts? |
| protected Set createExtensionArtifacts( String projectId, |
| List extensions ) |
| throws ProjectBuildingException |
| { |
| Set extensionArtifacts = new LinkedHashSet(); |
| |
| if ( extensions != null ) |
| { |
| for ( Iterator i = extensions.iterator(); i.hasNext(); ) |
| { |
| Extension ext = (Extension) i.next(); |
| |
| String version; |
| if ( StringUtils.isEmpty( ext.getVersion() ) ) |
| { |
| version = "RELEASE"; |
| } |
| else |
| { |
| version = ext.getVersion(); |
| } |
| |
| Artifact artifact; |
| try |
| { |
| VersionRange versionRange = VersionRange.createFromVersionSpec( version ); |
| artifact = |
| artifactFactory.createExtensionArtifact( ext.getGroupId(), ext.getArtifactId(), versionRange ); |
| } |
| catch ( InvalidVersionSpecificationException e ) |
| { |
| throw new ProjectBuildingException( projectId, "Unable to parse version '" + version + |
| "' for extension '" + ArtifactUtils.versionlessKey( ext.getGroupId(), ext.getArtifactId() ) + |
| "': " + e.getMessage(), e ); |
| } |
| |
| if ( artifact != null ) |
| { |
| extensionArtifacts.add( artifact ); |
| } |
| } |
| } |
| |
| return extensionArtifacts; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // |
| // ---------------------------------------------------------------------- |
| |
| private Model getSuperModel() |
| throws ProjectBuildingException |
| { |
| URL url = DefaultMavenProjectBuilder.class.getResource( "pom-" + MAVEN_MODEL_VERSION + ".xml" ); |
| |
| String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID ); |
| |
| return readModel( projectId, url, true ); |
| } |
| |
| public void contextualize( Context context ) |
| throws ContextException |
| { |
| container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void calculateConcreteState( MavenProject project, ProjectBuilderConfiguration config ) |
| throws ModelInterpolationException |
| { |
| calculateConcreteStateInternal( project, config, true, new HashSet() ); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void calculateConcreteState( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences ) |
| throws ModelInterpolationException |
| { |
| calculateConcreteStateInternal( project, config, processProjectReferences, ( processProjectReferences ? new HashSet() : null ) ); |
| } |
| |
| /* |
| * NOTE: This is a code hotspot, PLEASE be careful about the performance of logic inside or |
| * called from this method. |
| * |
| * NOTE: If processProjectReferences == false, processedProjects MUST NOT BE USED. It will be null. |
| */ |
| private void calculateConcreteStateInternal( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences, Set processedProjects ) |
| throws ModelInterpolationException |
| { |
| if ( processProjectReferences ) |
| { |
| processedProjects.add( project.getId() ); |
| } |
| |
| restoreDynamicStateInternal( project, config, processProjectReferences, processProjectReferences ? new HashSet( processedProjects ) : null ); |
| |
| if ( !project.isConcrete() ) |
| { |
| if ( project.getParent() != null ) |
| { |
| calculateConcreteStateInternal( project.getParent(), config, processProjectReferences, processedProjects ); |
| } |
| |
| Build build = project.getBuild(); |
| if ( build != null ) |
| { |
| initResourceMergeIds( build.getResources() ); |
| initResourceMergeIds( build.getTestResources() ); |
| } |
| |
| // NOTE: Since interpolation makes a copy through serialization, we don't need this. |
| // See note below. |
| // |
| // Model model = ModelUtils.cloneModel( project.getModel() ); |
| |
| File basedir = project.getBasedir(); |
| |
| // NOTE: If we ever get past serialization/deserialization for interpolation, we'll need to copy the model here! |
| Model model = ModelUtils.cloneModel( project.getModel() ); |
| model = modelInterpolator.interpolate( model, project.getBasedir(), config, getLogger().isDebugEnabled() ); |
| |
| List originalInterpolatedCompileSourceRoots = interpolateListOfStrings( project.getCompileSourceRoots(), |
| model, |
| project.getBasedir(), |
| config, |
| getLogger().isDebugEnabled() ); |
| |
| project.preserveCompileSourceRoots( originalInterpolatedCompileSourceRoots ); |
| |
| project.setCompileSourceRoots( originalInterpolatedCompileSourceRoots == null ? null |
| : translateListOfPaths( originalInterpolatedCompileSourceRoots, basedir ) ); |
| |
| List originalInterpolatedTestCompileSourceRoots = interpolateListOfStrings( project.getTestCompileSourceRoots(), |
| model, |
| project.getBasedir(), |
| config, |
| getLogger().isDebugEnabled() ); |
| |
| project.preserveTestCompileSourceRoots( originalInterpolatedTestCompileSourceRoots ); |
| project.setTestCompileSourceRoots( originalInterpolatedTestCompileSourceRoots == null ? null |
| : translateListOfPaths( originalInterpolatedTestCompileSourceRoots, basedir ) ); |
| |
| List originalInterpolatedScriptSourceRoots = interpolateListOfStrings( project.getScriptSourceRoots(), |
| model, |
| project.getBasedir(), |
| config, |
| getLogger().isDebugEnabled() ); |
| |
| project.preserveScriptSourceRoots( originalInterpolatedScriptSourceRoots ); |
| |
| // TODO: MNG-3731 |
| project.setScriptSourceRoots( originalInterpolatedScriptSourceRoots ); |
| // project.setScriptSourceRoots( originalInterpolatedScriptSourceRoots == null ? null |
| // : translateListOfPaths( originalInterpolatedScriptSourceRoots, basedir ) ); |
| |
| if ( basedir != null ) |
| { |
| pathTranslator.alignToBaseDirectory( model, basedir ); |
| } |
| |
| project.preserveBuild( ModelUtils.cloneBuild( model.getBuild() ) ); |
| project.preserveProperties(); |
| project.preserveBasedir(); |
| project.setBuild( model.getBuild() ); |
| |
| if ( project.getExecutionProject() != null ) |
| { |
| calculateConcreteStateInternal( project.getExecutionProject(), config, processProjectReferences, processedProjects ); |
| } |
| |
| project.setConcrete( true ); |
| } |
| |
| if ( processProjectReferences ) |
| { |
| calculateConcreteProjectReferences( project, config, processedProjects ); |
| } |
| } |
| |
| private void initResourceMergeIds( List resources ) |
| { |
| if ( resources != null ) |
| { |
| for ( Iterator it = resources.iterator(); it.hasNext(); ) |
| { |
| Resource resource = (Resource) it.next(); |
| |
| resource.initMergeId(); |
| } |
| } |
| } |
| |
| private void calculateConcreteProjectReferences( MavenProject project, |
| ProjectBuilderConfiguration config, |
| Set processedProjects ) |
| throws ModelInterpolationException |
| { |
| Map projectRefs = project.getProjectReferences(); |
| |
| if ( projectRefs != null ) |
| { |
| for ( Iterator it = projectRefs.values().iterator(); it.hasNext(); ) |
| { |
| MavenProject reference = (MavenProject) it.next(); |
| if ( !processedProjects.contains( reference.getId() ) ) |
| { |
| calculateConcreteStateInternal( reference, config, true, processedProjects ); |
| } |
| } |
| } |
| } |
| |
| private List translateListOfPaths( List paths, File basedir ) |
| { |
| if ( paths == null ) |
| { |
| return null; |
| } |
| else if ( basedir == null ) |
| { |
| return paths; |
| } |
| |
| List result = new ArrayList( paths.size() ); |
| for ( Iterator it = paths.iterator(); it.hasNext(); ) |
| { |
| String path = (String) it.next(); |
| |
| String aligned = pathTranslator.alignToBaseDirectory( path, basedir ); |
| |
| result.add( aligned ); |
| } |
| |
| return result; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void restoreDynamicState( MavenProject project, ProjectBuilderConfiguration config ) |
| throws ModelInterpolationException |
| { |
| restoreDynamicStateInternal( project, config, true, new HashSet() ); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void restoreDynamicState( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences ) |
| throws ModelInterpolationException |
| { |
| restoreDynamicStateInternal( project, config, processProjectReferences, ( processProjectReferences ? new HashSet() : null ) ); |
| } |
| |
| /* |
| * NOTE: This is a code hotspot, PLEASE be careful about the performance of logic inside or |
| * called from this method. |
| * |
| * NOTE: If processProjectReferences == false, processedProjects MUST NOT BE USED. It will be null. |
| */ |
| private void restoreDynamicStateInternal( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences, Set processedProjects ) |
| throws ModelInterpolationException |
| { |
| if ( processProjectReferences ) |
| { |
| processedProjects.add( project.getId() ); |
| } |
| |
| if ( project.isConcrete() && projectWasChanged( project ) ) |
| { |
| if ( project.getParent() != null ) |
| { |
| restoreDynamicStateInternal( project.getParent(), config, processProjectReferences, processedProjects ); |
| } |
| |
| restoreBuildRoots( project, config, getLogger().isDebugEnabled() ); |
| restoreModelBuildSection( project, config, getLogger().isDebugEnabled() ); |
| |
| if ( project.getExecutionProject() != null ) |
| { |
| restoreDynamicStateInternal( project.getExecutionProject(), config, processProjectReferences, processedProjects ); |
| } |
| |
| project.setConcrete( false ); |
| } |
| |
| if ( processProjectReferences ) |
| { |
| restoreDynamicProjectReferences( project, config, processedProjects ); |
| } |
| } |
| |
| private boolean projectWasChanged( MavenProject project ) |
| { |
| if ( !objectEquals( project.getBasedir(), project.getPreservedBasedir() ) ) |
| { |
| return true; |
| } |
| |
| if ( !objectEquals( project.getProperties(), project.getPreservedProperties() ) ) |
| { |
| return true; |
| } |
| |
| Build oBuild = project.getOriginalInterpolatedBuild(); |
| Build build = project.getBuild(); |
| |
| if ( !objectEquals( oBuild.getDirectory(), build.getDirectory() ) ) |
| { |
| return true; |
| } |
| |
| if ( !objectEquals( oBuild.getOutputDirectory(), build.getOutputDirectory() ) ) |
| { |
| return true; |
| } |
| |
| if ( !objectEquals( oBuild.getSourceDirectory(), build.getSourceDirectory() ) ) |
| { |
| return true; |
| } |
| |
| if ( !objectEquals( oBuild.getTestSourceDirectory(), build.getTestSourceDirectory() ) ) |
| { |
| return true; |
| } |
| |
| if ( !objectEquals( oBuild.getScriptSourceDirectory(), build.getScriptSourceDirectory() ) ) |
| { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| private boolean objectEquals( Object obj1, Object obj2 ) |
| { |
| return obj1 == null ? obj2 == null : obj2 != null && ( obj1 == obj2 || obj1.equals( obj2 ) ); |
| } |
| |
| private void propagateNewPlugins( MavenProject project ) |
| { |
| Build changedBuild = project.getBuild(); |
| Build dynamicBuild = project.getDynamicBuild(); |
| |
| if ( changedBuild == null || dynamicBuild == null ) |
| { |
| return; |
| } |
| |
| List changedPlugins = changedBuild.getPlugins(); |
| List dynamicPlugins = dynamicBuild.getPlugins(); |
| |
| if ( changedPlugins != null && dynamicPlugins != null && changedPlugins.size() != dynamicPlugins.size() ) |
| { |
| changedPlugins.removeAll( dynamicPlugins ); |
| if ( !changedPlugins.isEmpty() ) |
| { |
| for ( Iterator it = changedPlugins.iterator(); it.hasNext(); ) |
| { |
| Plugin plugin = (Plugin) it.next(); |
| |
| dynamicBuild.addPlugin( plugin ); |
| } |
| } |
| } |
| |
| dynamicBuild.flushPluginMap(); |
| } |
| |
| private void restoreDynamicProjectReferences( MavenProject project, |
| ProjectBuilderConfiguration config, |
| Set processedProjects ) |
| throws ModelInterpolationException |
| { |
| Map projectRefs = project.getProjectReferences(); |
| if ( projectRefs != null ) |
| { |
| for ( Iterator it = projectRefs.values().iterator(); it.hasNext(); ) |
| { |
| MavenProject projectRef = (MavenProject) it.next(); |
| if ( !processedProjects.contains( projectRef.getId() ) ) |
| { |
| restoreDynamicStateInternal( projectRef, config, true, processedProjects ); |
| } |
| } |
| } |
| } |
| |
| private void restoreBuildRoots( MavenProject project, |
| ProjectBuilderConfiguration config, |
| boolean debugMessages ) |
| throws ModelInterpolationException |
| { |
| project.setCompileSourceRoots( restoreListOfStrings( project.getDynamicCompileSourceRoots(), |
| project.getOriginalInterpolatedCompileSourceRoots(), |
| project.getCompileSourceRoots(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| project.setTestCompileSourceRoots( restoreListOfStrings( project.getDynamicTestCompileSourceRoots(), |
| project.getOriginalInterpolatedTestCompileSourceRoots(), |
| project.getTestCompileSourceRoots(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| project.setScriptSourceRoots( restoreListOfStrings( project.getDynamicScriptSourceRoots(), |
| project.getOriginalInterpolatedScriptSourceRoots(), |
| project.getScriptSourceRoots(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| project.clearRestorableRoots(); |
| } |
| |
| private void restoreModelBuildSection( MavenProject project, |
| ProjectBuilderConfiguration config, |
| boolean debugMessages ) |
| throws ModelInterpolationException |
| { |
| Build changedBuild = project.getBuild(); |
| Build dynamicBuild = project.getDynamicBuild(); |
| Build originalInterpolatedBuild = project.getOriginalInterpolatedBuild(); |
| |
| dynamicBuild.setResources( restoreResources( dynamicBuild.getResources(), |
| originalInterpolatedBuild.getResources(), |
| changedBuild.getResources(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setTestResources( restoreResources( dynamicBuild.getTestResources(), |
| originalInterpolatedBuild.getTestResources(), |
| changedBuild.getTestResources(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setFilters( restoreListOfStrings( dynamicBuild.getFilters(), |
| originalInterpolatedBuild.getFilters(), |
| changedBuild.getFilters(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setFinalName( restoreString( dynamicBuild.getFinalName(), |
| originalInterpolatedBuild.getFinalName(), |
| changedBuild.getFinalName(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setDefaultGoal( restoreString( dynamicBuild.getDefaultGoal(), |
| originalInterpolatedBuild.getDefaultGoal(), |
| changedBuild.getDefaultGoal(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setSourceDirectory( restoreString( dynamicBuild.getSourceDirectory(), |
| originalInterpolatedBuild.getSourceDirectory(), |
| changedBuild.getSourceDirectory(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setTestSourceDirectory( restoreString( dynamicBuild.getTestSourceDirectory(), |
| originalInterpolatedBuild.getTestSourceDirectory(), |
| changedBuild.getTestSourceDirectory(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setScriptSourceDirectory( restoreString( dynamicBuild.getScriptSourceDirectory(), |
| originalInterpolatedBuild.getScriptSourceDirectory(), |
| changedBuild.getScriptSourceDirectory(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setOutputDirectory( restoreString( dynamicBuild.getOutputDirectory(), |
| originalInterpolatedBuild.getOutputDirectory(), |
| changedBuild.getOutputDirectory(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setTestOutputDirectory( restoreString( dynamicBuild.getTestOutputDirectory(), |
| originalInterpolatedBuild.getTestOutputDirectory(), |
| changedBuild.getTestOutputDirectory(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| dynamicBuild.setDirectory( restoreString( dynamicBuild.getDirectory(), |
| originalInterpolatedBuild.getDirectory(), |
| changedBuild.getDirectory(), |
| project, |
| config, |
| debugMessages ) ); |
| |
| propagateNewPlugins( project ); |
| |
| project.setBuild( dynamicBuild ); |
| |
| project.clearRestorableBuild(); |
| } |
| |
| private List interpolateListOfStrings( List originalStrings, |
| Model model, |
| File projectDir, |
| ProjectBuilderConfiguration config, |
| boolean debugMessages ) |
| throws ModelInterpolationException |
| { |
| if ( originalStrings == null ) |
| { |
| return null; |
| } |
| |
| List result = new ArrayList(); |
| |
| for ( Iterator it = originalStrings.iterator(); it.hasNext(); ) |
| { |
| String original = (String) it.next(); |
| String interpolated = modelInterpolator.interpolate( original, model, projectDir, config, debugMessages ); |
| |
| result.add( interpolated ); |
| } |
| |
| return result; |
| } |
| |
| private String restoreString( String originalString, |
| String originalInterpolatedString, |
| String changedString, |
| MavenProject project, |
| ProjectBuilderConfiguration config, |
| boolean debugMessages ) |
| throws ModelInterpolationException |
| { |
| if ( originalString == null ) |
| { |
| return changedString; |
| } |
| else if ( changedString == null ) |
| { |
| return originalString; |
| } |
| |
| Model model = project.getModel(); |
| |
| String relativeChangedString; |
| if ( project.getBasedir() != null ) |
| { |
| relativeChangedString = pathTranslator.unalignFromBaseDirectory( changedString, project.getBasedir() ); |
| } |
| else |
| { |
| relativeChangedString = changedString; |
| } |
| |
| String interpolatedOriginal = modelInterpolator.interpolate( originalString, |
| model, |
| project.getBasedir(), |
| config, |
| debugMessages ); |
| |
| interpolatedOriginal = pathTranslator.unalignFromBaseDirectory( interpolatedOriginal, project.getBasedir() ); |
| |
| String interpolatedOriginal2 = modelInterpolator.interpolate( originalInterpolatedString, |
| model, |
| project.getBasedir(), |
| config, |
| debugMessages ); |
| |
| interpolatedOriginal2 = pathTranslator.alignToBaseDirectory( interpolatedOriginal2, project.getBasedir() ); |
| |
| String interpolatedChanged = modelInterpolator.interpolate( changedString, |
| model, |
| project.getBasedir(), |
| config, |
| debugMessages ); |
| |
| interpolatedChanged = pathTranslator.alignToBaseDirectory( interpolatedChanged, project.getBasedir() ); |
| |
| String relativeInterpolatedChanged = modelInterpolator.interpolate( relativeChangedString, |
| model, |
| project.getBasedir(), |
| config, |
| debugMessages ); |
| |
| if ( interpolatedOriginal.equals( interpolatedChanged ) || interpolatedOriginal2.equals( interpolatedChanged ) ) |
| { |
| return originalString; |
| } |
| else if ( interpolatedOriginal.equals( relativeInterpolatedChanged ) |
| || interpolatedOriginal2.equals( relativeInterpolatedChanged ) ) |
| { |
| return originalString; |
| } |
| |
| return relativeChangedString; |
| } |
| |
| private List restoreListOfStrings( List originalStrings, |
| List originalInterpolatedStrings, |
| List changedStrings, |
| MavenProject project, |
| ProjectBuilderConfiguration config, |
| boolean debugMessages ) |
| throws ModelInterpolationException |
| { |
| if ( originalStrings == null ) |
| { |
| return changedStrings; |
| } |
| else if ( changedStrings == null ) |
| { |
| return originalStrings; |
| } |
| |
| List result = new ArrayList(); |
| |
| Map orig = new HashMap(); |
| for ( int idx = 0; idx < originalStrings.size(); idx++ ) |
| { |
| String[] permutations = new String[2]; |
| |
| permutations[0] = pathTranslator.alignToBaseDirectory( (String) originalInterpolatedStrings.get( idx ), project.getBasedir() ); |
| permutations[1] = (String) originalStrings.get( idx ); |
| |
| orig.put( permutations[0], permutations ); |
| } |
| |
| for ( Iterator it = changedStrings.iterator(); it.hasNext(); ) |
| { |
| String changedString = (String) it.next(); |
| String relativeChangedString; |
| if ( project.getBasedir() != null ) |
| { |
| relativeChangedString = pathTranslator.unalignFromBaseDirectory( changedString, project.getBasedir() ); |
| } |
| else |
| { |
| relativeChangedString = changedString; |
| } |
| |
| String interpolated = modelInterpolator.interpolate( changedString, |
| project.getModel(), |
| project.getBasedir(), |
| config, |
| debugMessages ); |
| |
| interpolated = pathTranslator.alignToBaseDirectory( interpolated, project.getBasedir() ); |
| |
| String relativeInterpolated = modelInterpolator.interpolate( relativeChangedString, |
| project.getModel(), |
| project.getBasedir(), |
| config, |
| debugMessages ); |
| |
| String[] original = (String[]) orig.get( interpolated ); |
| if ( original == null ) |
| { |
| original = (String[]) orig.get( relativeInterpolated ); |
| } |
| |
| if ( original == null ) |
| { |
| result.add( relativeChangedString ); |
| } |
| else |
| { |
| result.add( original[1] ); |
| } |
| } |
| |
| return result; |
| } |
| |
| private List restoreResources( List originalResources, |
| List originalInterpolatedResources, |
| List changedResources, |
| MavenProject project, |
| ProjectBuilderConfiguration config, |
| boolean debugMessages ) |
| throws ModelInterpolationException |
| { |
| if ( originalResources == null || changedResources == null ) |
| { |
| return originalResources; |
| } |
| |
| List result = new ArrayList(); |
| |
| Map originalResourcesByMergeId = new HashMap(); |
| for ( int idx = 0; idx < originalResources.size(); idx++ ) |
| { |
| Resource[] permutations = new Resource[2]; |
| |
| permutations[0] = (Resource) originalInterpolatedResources.get( idx ); |
| permutations[1] = (Resource) originalResources.get( idx ); |
| |
| originalResourcesByMergeId.put( permutations[0].getMergeId(), permutations ); |
| } |
| |
| for ( Iterator it = changedResources.iterator(); it.hasNext(); ) |
| { |
| Resource resource = (Resource) it.next(); |
| String mergeId = resource.getMergeId(); |
| if ( mergeId == null || !originalResourcesByMergeId.containsKey( mergeId ) ) |
| { |
| result.add( resource ); |
| } |
| else |
| { |
| Resource originalInterpolatedResource = ( (Resource[]) originalResourcesByMergeId.get( mergeId ) )[0]; |
| Resource originalResource = ( (Resource[]) originalResourcesByMergeId.get( mergeId ) )[1]; |
| |
| String dir = modelInterpolator.interpolate( resource.getDirectory(), project.getModel(), project.getBasedir(), config, getLogger().isDebugEnabled() ); |
| String oDir = originalInterpolatedResource.getDirectory(); |
| |
| if ( !dir.equals( oDir ) ) |
| { |
| originalResource.setDirectory( pathTranslator.unalignFromBaseDirectory( dir, project.getBasedir() ) ); |
| } |
| |
| if ( resource.getTargetPath() != null ) |
| { |
| String target = modelInterpolator.interpolate( resource.getTargetPath(), project.getModel(), project.getBasedir(), config, getLogger().isDebugEnabled() ); |
| |
| String oTarget = originalInterpolatedResource.getTargetPath(); |
| |
| if ( !target.equals( oTarget ) ) |
| { |
| originalResource.setTargetPath( pathTranslator.unalignFromBaseDirectory( target, project.getBasedir() ) ); |
| } |
| } |
| |
| originalResource.setFiltering( resource.isFiltering() ); |
| |
| originalResource.setExcludes( collectRestoredListOfPatterns( resource.getExcludes(), |
| originalResource.getExcludes(), |
| originalInterpolatedResource.getExcludes() ) ); |
| |
| originalResource.setIncludes( collectRestoredListOfPatterns( resource.getIncludes(), |
| originalResource.getIncludes(), |
| originalInterpolatedResource.getIncludes() ) ); |
| |
| result.add( originalResource ); |
| } |
| } |
| |
| return result; |
| } |
| |
| private List collectRestoredListOfPatterns( List patterns, |
| List originalPatterns, |
| List originalInterpolatedPatterns ) |
| { |
| LinkedHashSet collectedPatterns = new LinkedHashSet(); |
| |
| collectedPatterns.addAll( originalPatterns ); |
| |
| for ( Iterator it = patterns.iterator(); it.hasNext(); ) |
| { |
| String pattern = (String) it.next(); |
| if ( !originalInterpolatedPatterns.contains( pattern ) ) |
| { |
| collectedPatterns.add( pattern ); |
| } |
| } |
| |
| return collectedPatterns.isEmpty() ? Collections.EMPTY_LIST |
| : new ArrayList( collectedPatterns ); |
| } |
| |
| } |