View Javadoc
1   package org.apache.maven.project;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.List;
26  import java.util.Properties;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.InvalidRepositoryException;
30  import org.apache.maven.artifact.repository.ArtifactRepository;
31  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
32  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
33  import org.apache.maven.execution.MavenExecutionRequest;
34  import org.apache.maven.execution.MavenSession;
35  import org.apache.maven.model.Repository;
36  import org.apache.maven.model.building.ModelBuildingException;
37  import org.apache.maven.model.building.ModelBuildingRequest;
38  import org.apache.maven.model.building.ModelSource;
39  import org.apache.maven.model.building.UrlModelSource;
40  import org.apache.maven.plugin.LegacySupport;
41  import org.apache.maven.profiles.ProfileManager;
42  import org.apache.maven.properties.internal.EnvironmentUtils;
43  import org.apache.maven.repository.RepositorySystem;
44  import org.apache.maven.wagon.events.TransferListener;
45  import org.codehaus.plexus.component.annotations.Component;
46  import org.codehaus.plexus.component.annotations.Requirement;
47  
48  /**
49   */
50  @Component( role = MavenProjectBuilder.class )
51  @Deprecated
52  public class DefaultMavenProjectBuilder
53      implements MavenProjectBuilder
54  {
55  
56      @Requirement
57      private ProjectBuilder projectBuilder;
58  
59      @Requirement
60      private RepositorySystem repositorySystem;
61  
62      @Requirement
63      private LegacySupport legacySupport;
64  
65      // ----------------------------------------------------------------------
66      // MavenProjectBuilder Implementation
67      // ----------------------------------------------------------------------
68  
69      private ProjectBuildingRequest toRequest( ProjectBuilderConfiguration configuration )
70      {
71          DefaultProjectBuildingRequest request = new DefaultProjectBuildingRequest();
72  
73          request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
74          request.setResolveDependencies( false );
75  
76          request.setLocalRepository( configuration.getLocalRepository() );
77          request.setBuildStartTime( configuration.getBuildStartTime() );
78          request.setUserProperties( configuration.getUserProperties() );
79          request.setSystemProperties( configuration.getExecutionProperties() );
80  
81          ProfileManager profileManager = configuration.getGlobalProfileManager();
82          if ( profileManager != null )
83          {
84              request.setActiveProfileIds( profileManager.getExplicitlyActivatedIds() );
85              request.setInactiveProfileIds( profileManager.getExplicitlyDeactivatedIds() );
86          }
87          else
88          {
89              /*
90               * MNG-4900: Hack to workaround deficiency of legacy API which makes it impossible for plugins to access the
91               * global profile manager which is required to build a POM like a CLI invocation does. Failure to consider
92               * the activated profiles can cause repo declarations to be lost which in turn will result in artifact
93               * resolution failures, in particular when using the enhanced local repo which guards access to local files
94               * based on the configured remote repos.
95               */
96              MavenSession session = legacySupport.getSession();
97              if ( session != null )
98              {
99                  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 }