View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.project;
20  
21  import java.io.File;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.List;
25  import java.util.Properties;
26  import org.apache.maven.artifact.Artifact;
27  import org.apache.maven.artifact.InvalidRepositoryException;
28  import org.apache.maven.artifact.repository.ArtifactRepository;
29  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
30  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
31  import org.apache.maven.execution.MavenExecutionRequest;
32  import org.apache.maven.execution.MavenSession;
33  import org.apache.maven.model.Repository;
34  import org.apache.maven.model.building.ModelBuildingException;
35  import org.apache.maven.model.building.ModelBuildingRequest;
36  import org.apache.maven.model.building.ModelSource;
37  import org.apache.maven.model.building.UrlModelSource;
38  import org.apache.maven.plugin.LegacySupport;
39  import org.apache.maven.profiles.ProfileManager;
40  import org.apache.maven.properties.internal.EnvironmentUtils;
41  import org.apache.maven.repository.RepositorySystem;
42  import org.apache.maven.wagon.events.TransferListener;
43  import org.codehaus.plexus.component.annotations.Component;
44  import org.codehaus.plexus.component.annotations.Requirement;
45  
46  /**
47   */
48  @Component(role = MavenProjectBuilder.class)
49  @Deprecated
50  public class DefaultMavenProjectBuilder implements MavenProjectBuilder {
51  
52      @Requirement
53      private ProjectBuilder projectBuilder;
54  
55      @Requirement
56      private RepositorySystem repositorySystem;
57  
58      @Requirement
59      private LegacySupport legacySupport;
60  
61      // ----------------------------------------------------------------------
62      // MavenProjectBuilder Implementation
63      // ----------------------------------------------------------------------
64  
65      private ProjectBuildingRequest toRequest(ProjectBuilderConfiguration configuration) {
66          DefaultProjectBuildingRequest request = new DefaultProjectBuildingRequest();
67  
68          request.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0);
69          request.setResolveDependencies(false);
70  
71          request.setLocalRepository(configuration.getLocalRepository());
72          request.setBuildStartTime(configuration.getBuildStartTime());
73          request.setUserProperties(configuration.getUserProperties());
74          request.setSystemProperties(configuration.getExecutionProperties());
75  
76          ProfileManager profileManager = configuration.getGlobalProfileManager();
77          if (profileManager != null) {
78              request.setActiveProfileIds(profileManager.getExplicitlyActivatedIds());
79              request.setInactiveProfileIds(profileManager.getExplicitlyDeactivatedIds());
80          } else {
81              /*
82               * MNG-4900: Hack to workaround deficiency of legacy API which makes it impossible for plugins to access the
83               * global profile manager which is required to build a POM like a CLI invocation does. Failure to consider
84               * the activated profiles can cause repo declarations to be lost which in turn will result in artifact
85               * resolution failures, in particular when using the enhanced local repo which guards access to local files
86               * based on the configured remote repos.
87               */
88              MavenSession session = legacySupport.getSession();
89              if (session != null) {
90                  MavenExecutionRequest req = session.getRequest();
91                  if (req != null) {
92                      request.setActiveProfileIds(req.getActiveProfiles());
93                      request.setInactiveProfileIds(req.getInactiveProfiles());
94                  }
95              }
96          }
97  
98          return request;
99      }
100 
101     private ProjectBuildingRequest injectSession(ProjectBuildingRequest request) {
102         MavenSession session = legacySupport.getSession();
103         if (session != null) {
104             request.setRepositorySession(session.getRepositorySession());
105             request.setSystemProperties(session.getSystemProperties());
106             if (request.getUserProperties().isEmpty()) {
107                 request.setUserProperties(session.getUserProperties());
108             }
109 
110             MavenExecutionRequest req = session.getRequest();
111             if (req != null) {
112                 request.setRemoteRepositories(req.getRemoteRepositories());
113             }
114         } else {
115             Properties props = new Properties();
116             EnvironmentUtils.addEnvVars(props);
117             props.putAll(System.getProperties());
118             request.setSystemProperties(props);
119         }
120 
121         return request;
122     }
123 
124     @SuppressWarnings("unchecked")
125     private List<ArtifactRepository> normalizeToArtifactRepositories(
126             List<?> repositories, ProjectBuildingRequest request) throws ProjectBuildingException {
127         /*
128          * This provides backward-compat with 2.x that allowed plugins like the maven-remote-resources-plugin:1.0 to
129          * populate the builder configuration with model repositories instead of artifact repositories.
130          */
131 
132         if (repositories != null) {
133             boolean normalized = false;
134 
135             List<ArtifactRepository> repos = new ArrayList<>(repositories.size());
136 
137             for (Object repository : repositories) {
138                 if (repository instanceof Repository) {
139                     try {
140                         ArtifactRepository repo = repositorySystem.buildArtifactRepository((Repository) repository);
141                         repositorySystem.injectMirror(request.getRepositorySession(), Arrays.asList(repo));
142                         repositorySystem.injectProxy(request.getRepositorySession(), Arrays.asList(repo));
143                         repositorySystem.injectAuthentication(request.getRepositorySession(), Arrays.asList(repo));
144                         repos.add(repo);
145                     } catch (InvalidRepositoryException e) {
146                         throw new ProjectBuildingException("", "Invalid remote repository " + repository, e);
147                     }
148                     normalized = true;
149                 } else {
150                     repos.add((ArtifactRepository) repository);
151                 }
152             }
153 
154             if (normalized) {
155                 return repos;
156             }
157         }
158 
159         return (List<ArtifactRepository>) repositories;
160     }
161 
162     private ProjectBuildingException transformError(ProjectBuildingException e) {
163         if (e.getCause() instanceof ModelBuildingException) {
164             return new InvalidProjectModelException(e.getProjectId(), e.getMessage(), e.getPomFile());
165         }
166 
167         return e;
168     }
169 
170     public MavenProject build(File pom, ProjectBuilderConfiguration configuration) throws ProjectBuildingException {
171         ProjectBuildingRequest request = injectSession(toRequest(configuration));
172 
173         try {
174             return projectBuilder.build(pom, request).getProject();
175         } catch (ProjectBuildingException e) {
176             throw transformError(e);
177         }
178     }
179 
180     // This is used by the SITE plugin.
181     public MavenProject build(File pom, ArtifactRepository localRepository, ProfileManager profileManager)
182             throws ProjectBuildingException {
183         ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
184         configuration.setLocalRepository(localRepository);
185         configuration.setGlobalProfileManager(profileManager);
186 
187         return build(pom, configuration);
188     }
189 
190     public MavenProject buildFromRepository(
191             Artifact artifact,
192             List<ArtifactRepository> remoteRepositories,
193             ProjectBuilderConfiguration configuration,
194             boolean allowStubModel)
195             throws ProjectBuildingException {
196         ProjectBuildingRequest request = injectSession(toRequest(configuration));
197         request.setRemoteRepositories(normalizeToArtifactRepositories(remoteRepositories, request));
198         request.setProcessPlugins(false);
199         request.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
200 
201         try {
202             return projectBuilder.build(artifact, allowStubModel, request).getProject();
203         } catch (ProjectBuildingException e) {
204             throw transformError(e);
205         }
206     }
207 
208     public MavenProject buildFromRepository(
209             Artifact artifact,
210             List<ArtifactRepository> remoteRepositories,
211             ArtifactRepository localRepository,
212             boolean allowStubModel)
213             throws ProjectBuildingException {
214         ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
215         configuration.setLocalRepository(localRepository);
216 
217         return buildFromRepository(artifact, remoteRepositories, configuration, allowStubModel);
218     }
219 
220     public MavenProject buildFromRepository(
221             Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository)
222             throws ProjectBuildingException {
223         return buildFromRepository(artifact, remoteRepositories, localRepository, true);
224     }
225 
226     /**
227      * This is used for pom-less execution like running archetype:generate. I am taking out the profile handling and the
228      * interpolation of the base directory until we spec this out properly.
229      */
230     public MavenProject buildStandaloneSuperProject(ProjectBuilderConfiguration configuration)
231             throws ProjectBuildingException {
232         ProjectBuildingRequest request = injectSession(toRequest(configuration));
233         request.setProcessPlugins(false);
234         request.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
235 
236         ModelSource modelSource = new UrlModelSource(getClass().getResource("standalone.xml"));
237 
238         MavenProject project = projectBuilder.build(modelSource, request).getProject();
239         project.setExecutionRoot(true);
240         return project;
241     }
242 
243     public MavenProject buildStandaloneSuperProject(ArtifactRepository localRepository)
244             throws ProjectBuildingException {
245         return buildStandaloneSuperProject(localRepository, null);
246     }
247 
248     public MavenProject buildStandaloneSuperProject(ArtifactRepository localRepository, ProfileManager profileManager)
249             throws ProjectBuildingException {
250         ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
251         configuration.setLocalRepository(localRepository);
252         configuration.setGlobalProfileManager(profileManager);
253 
254         return buildStandaloneSuperProject(configuration);
255     }
256 
257     public MavenProject buildWithDependencies(
258             File pom,
259             ArtifactRepository localRepository,
260             ProfileManager profileManager,
261             TransferListener transferListener)
262             throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException {
263         ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
264         configuration.setLocalRepository(localRepository);
265         configuration.setGlobalProfileManager(profileManager);
266 
267         ProjectBuildingRequest request = injectSession(toRequest(configuration));
268 
269         request.setResolveDependencies(true);
270 
271         try {
272             return projectBuilder.build(pom, request).getProject();
273         } catch (ProjectBuildingException e) {
274             throw transformError(e);
275         }
276     }
277 
278     public MavenProject buildWithDependencies(
279             File pom, ArtifactRepository localRepository, ProfileManager profileManager)
280             throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException {
281         return buildWithDependencies(pom, localRepository, profileManager, null);
282     }
283 }