001 package org.apache.maven.project; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.io.File; 023 import java.util.ArrayList; 024 import java.util.Arrays; 025 import java.util.List; 026 import java.util.Properties; 027 028 import org.apache.maven.artifact.Artifact; 029 import org.apache.maven.artifact.InvalidRepositoryException; 030 import org.apache.maven.artifact.repository.ArtifactRepository; 031 import org.apache.maven.artifact.resolver.ArtifactNotFoundException; 032 import org.apache.maven.artifact.resolver.ArtifactResolutionException; 033 import org.apache.maven.execution.MavenExecutionRequest; 034 import org.apache.maven.execution.MavenSession; 035 import org.apache.maven.model.Repository; 036 import org.apache.maven.model.building.ModelBuildingException; 037 import org.apache.maven.model.building.ModelBuildingRequest; 038 import org.apache.maven.model.building.ModelSource; 039 import org.apache.maven.model.building.UrlModelSource; 040 import org.apache.maven.plugin.LegacySupport; 041 import org.apache.maven.profiles.ProfileManager; 042 import org.apache.maven.properties.internal.EnvironmentUtils; 043 import org.apache.maven.repository.RepositorySystem; 044 import org.apache.maven.wagon.events.TransferListener; 045 import org.codehaus.plexus.component.annotations.Component; 046 import org.codehaus.plexus.component.annotations.Requirement; 047 048 /** 049 */ 050 @Component( role = MavenProjectBuilder.class ) 051 @Deprecated 052 public class DefaultMavenProjectBuilder 053 implements MavenProjectBuilder 054 { 055 056 @Requirement 057 private ProjectBuilder projectBuilder; 058 059 @Requirement 060 private RepositorySystem repositorySystem; 061 062 @Requirement 063 private LegacySupport legacySupport; 064 065 // ---------------------------------------------------------------------- 066 // MavenProjectBuilder Implementation 067 // ---------------------------------------------------------------------- 068 069 private ProjectBuildingRequest toRequest( ProjectBuilderConfiguration configuration ) 070 { 071 DefaultProjectBuildingRequest request = new DefaultProjectBuildingRequest(); 072 073 request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 ); 074 request.setResolveDependencies( false ); 075 076 request.setLocalRepository( configuration.getLocalRepository() ); 077 request.setBuildStartTime( configuration.getBuildStartTime() ); 078 request.setUserProperties( configuration.getUserProperties() ); 079 request.setSystemProperties( configuration.getExecutionProperties() ); 080 081 ProfileManager profileManager = configuration.getGlobalProfileManager(); 082 if ( profileManager != null ) 083 { 084 request.setActiveProfileIds( profileManager.getExplicitlyActivatedIds() ); 085 request.setInactiveProfileIds( profileManager.getExplicitlyDeactivatedIds() ); 086 } 087 else 088 { 089 /* 090 * MNG-4900: Hack to workaround deficiency of legacy API which makes it impossible for plugins to access the 091 * global profile manager which is required to build a POM like a CLI invocation does. Failure to consider 092 * the activated profiles can cause repo declarations to be lost which in turn will result in artifact 093 * resolution failures, in particular when using the enhanced local repo which guards access to local files 094 * based on the configured remote repos. 095 */ 096 MavenSession session = legacySupport.getSession(); 097 if ( session != null ) 098 { 099 MavenExecutionRequest req = session.getRequest(); 100 if ( req != null ) 101 { 102 request.setActiveProfileIds( req.getActiveProfiles() ); 103 request.setInactiveProfileIds( req.getInactiveProfiles() ); 104 } 105 } 106 } 107 108 return request; 109 } 110 111 private ProjectBuildingRequest injectSession( ProjectBuildingRequest request ) 112 { 113 MavenSession session = legacySupport.getSession(); 114 if ( session != null ) 115 { 116 request.setRepositorySession( session.getRepositorySession() ); 117 request.setSystemProperties( session.getSystemProperties() ); 118 if ( request.getUserProperties().isEmpty() ) 119 { 120 request.setUserProperties( session.getUserProperties() ); 121 } 122 123 MavenExecutionRequest req = session.getRequest(); 124 if ( req != null ) 125 { 126 request.setRemoteRepositories( req.getRemoteRepositories() ); 127 } 128 } 129 else 130 { 131 Properties props = new Properties(); 132 EnvironmentUtils.addEnvVars( props ); 133 props.putAll( System.getProperties() ); 134 request.setSystemProperties( props ); 135 } 136 137 return request; 138 } 139 140 @SuppressWarnings( "unchecked" ) 141 private List<ArtifactRepository> normalizeToArtifactRepositories( List<?> repositories, 142 ProjectBuildingRequest request ) 143 throws ProjectBuildingException 144 { 145 /* 146 * This provides backward-compat with 2.x that allowed plugins like the maven-remote-resources-plugin:1.0 to 147 * populate the builder configuration with model repositories instead of artifact repositories. 148 */ 149 150 if ( repositories != null ) 151 { 152 boolean normalized = false; 153 154 List<ArtifactRepository> repos = new ArrayList<ArtifactRepository>( repositories.size() ); 155 156 for ( Object repository : repositories ) 157 { 158 if ( repository instanceof Repository ) 159 { 160 try 161 { 162 ArtifactRepository repo = repositorySystem.buildArtifactRepository( (Repository) repository ); 163 repositorySystem.injectMirror( request.getRepositorySession(), Arrays.asList( repo ) ); 164 repositorySystem.injectProxy( request.getRepositorySession(), Arrays.asList( repo ) ); 165 repositorySystem.injectAuthentication( request.getRepositorySession(), Arrays.asList( repo ) ); 166 repos.add( repo ); 167 } 168 catch ( InvalidRepositoryException e ) 169 { 170 throw new ProjectBuildingException( "", "Invalid remote repository " + repository, e ); 171 } 172 normalized = true; 173 } 174 else 175 { 176 repos.add( (ArtifactRepository) repository ); 177 } 178 } 179 180 if ( normalized ) 181 { 182 return repos; 183 } 184 } 185 186 return (List<ArtifactRepository>) repositories; 187 } 188 189 private ProjectBuildingException transformError( ProjectBuildingException e ) 190 { 191 if ( e.getCause() instanceof ModelBuildingException ) 192 { 193 return new InvalidProjectModelException( e.getProjectId(), e.getMessage(), e.getPomFile() ); 194 } 195 196 return e; 197 } 198 199 public MavenProject build( File pom, ProjectBuilderConfiguration configuration ) 200 throws ProjectBuildingException 201 { 202 ProjectBuildingRequest request = injectSession( toRequest( configuration ) ); 203 204 try 205 { 206 return projectBuilder.build( pom, request ).getProject(); 207 } 208 catch ( ProjectBuildingException e ) 209 { 210 throw transformError( e ); 211 } 212 } 213 214 // This is used by the SITE plugin. 215 public MavenProject build( File pom, ArtifactRepository localRepository, ProfileManager profileManager ) 216 throws ProjectBuildingException 217 { 218 ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration(); 219 configuration.setLocalRepository( localRepository ); 220 configuration.setGlobalProfileManager( profileManager ); 221 222 return build( pom, configuration ); 223 } 224 225 public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories, 226 ProjectBuilderConfiguration configuration, boolean allowStubModel ) 227 throws ProjectBuildingException 228 { 229 ProjectBuildingRequest request = injectSession( toRequest( configuration ) ); 230 request.setRemoteRepositories( normalizeToArtifactRepositories( remoteRepositories, request ) ); 231 request.setProcessPlugins( false ); 232 request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL ); 233 234 try 235 { 236 return projectBuilder.build( artifact, allowStubModel, request ).getProject(); 237 } 238 catch ( ProjectBuildingException e ) 239 { 240 throw transformError( e ); 241 } 242 } 243 244 public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories, 245 ArtifactRepository localRepository, boolean allowStubModel ) 246 throws ProjectBuildingException 247 { 248 ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration(); 249 configuration.setLocalRepository( localRepository ); 250 251 return buildFromRepository( artifact, remoteRepositories, configuration, allowStubModel ); 252 } 253 254 public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories, 255 ArtifactRepository localRepository ) 256 throws ProjectBuildingException 257 { 258 return buildFromRepository( artifact, remoteRepositories, localRepository, true ); 259 } 260 261 /** 262 * This is used for pom-less execution like running archetype:generate. I am taking out the profile handling and the 263 * interpolation of the base directory until we spec this out properly. 264 */ 265 public MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration configuration ) 266 throws ProjectBuildingException 267 { 268 ProjectBuildingRequest request = injectSession( toRequest( configuration ) ); 269 request.setProcessPlugins( false ); 270 request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL ); 271 272 ModelSource modelSource = new UrlModelSource( getClass().getResource( "standalone.xml" ) ); 273 274 MavenProject project = projectBuilder.build( modelSource, request ).getProject(); 275 project.setExecutionRoot( true ); 276 return project; 277 } 278 279 public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository ) 280 throws ProjectBuildingException 281 { 282 return buildStandaloneSuperProject( localRepository, null ); 283 } 284 285 public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository, ProfileManager profileManager ) 286 throws ProjectBuildingException 287 { 288 ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration(); 289 configuration.setLocalRepository( localRepository ); 290 configuration.setGlobalProfileManager( profileManager ); 291 292 return buildStandaloneSuperProject( configuration ); 293 } 294 295 public MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository, 296 ProfileManager profileManager, TransferListener transferListener ) 297 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException 298 { 299 ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration(); 300 configuration.setLocalRepository( localRepository ); 301 configuration.setGlobalProfileManager( profileManager ); 302 303 ProjectBuildingRequest request = injectSession( toRequest( configuration ) ); 304 305 request.setResolveDependencies( true ); 306 307 try 308 { 309 return projectBuilder.build( pom, request ).getProject(); 310 } 311 catch ( ProjectBuildingException e ) 312 { 313 throw transformError( e ); 314 } 315 } 316 317 public MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository, 318 ProfileManager profileManager ) 319 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException 320 { 321 return buildWithDependencies( pom, localRepository, profileManager, null ); 322 } 323 324 }