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;
20  
21  import javax.inject.Inject;
22  
23  import java.io.File;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.List;
27  import java.util.Properties;
28  
29  import org.apache.maven.artifact.Artifact;
30  import org.apache.maven.artifact.InvalidRepositoryException;
31  import org.apache.maven.artifact.repository.ArtifactRepository;
32  import org.apache.maven.bridge.MavenRepositorySystem;
33  import org.apache.maven.execution.DefaultMavenExecutionRequest;
34  import org.apache.maven.execution.DefaultMavenExecutionResult;
35  import org.apache.maven.execution.MavenExecutionRequest;
36  import org.apache.maven.execution.MavenSession;
37  import org.apache.maven.model.Build;
38  import org.apache.maven.model.Dependency;
39  import org.apache.maven.model.Exclusion;
40  import org.apache.maven.model.Model;
41  import org.apache.maven.model.Plugin;
42  import org.apache.maven.model.Repository;
43  import org.apache.maven.model.RepositoryPolicy;
44  import org.apache.maven.project.DefaultProjectBuildingRequest;
45  import org.apache.maven.project.MavenProject;
46  import org.apache.maven.project.ProjectBuildingRequest;
47  import org.apache.maven.repository.RepositorySystem;
48  import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
49  import org.codehaus.plexus.ContainerConfiguration;
50  import org.codehaus.plexus.PlexusConstants;
51  import org.codehaus.plexus.PlexusContainer;
52  import org.codehaus.plexus.util.FileUtils;
53  import org.eclipse.aether.DefaultRepositorySystemSession;
54  import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
55  import org.eclipse.aether.repository.LocalRepository;
56  
57  import static org.codehaus.plexus.testing.PlexusExtension.getBasedir;
58  
59  public abstract class AbstractCoreMavenComponentTestCase {
60  
61      @Inject
62      protected MavenRepositorySystem repositorySystem;
63  
64      @Inject
65      protected org.apache.maven.project.ProjectBuilder projectBuilder;
66  
67      @Inject
68      protected PlexusContainer container;
69  
70      protected abstract String getProjectsDirectory();
71  
72      protected File getProject(String name) throws Exception {
73          File source = new File(new File(getBasedir(), getProjectsDirectory()), name);
74          File target = new File(new File(getBasedir(), "target"), name);
75          FileUtils.copyDirectoryStructureIfModified(source, target);
76          return new File(target, "pom.xml");
77      }
78  
79      /**
80       * We need to customize the standard Plexus container with the plugin discovery listener which
81       * is what looks for the META-INF/maven/plugin.xml resources that enter the system when a Maven
82       * plugin is loaded.
83       *
84       * We also need to customize the Plexus container with a standard plugin discovery listener
85       * which is the MavenPluginCollector. When a Maven plugin is discovered the MavenPluginCollector
86       * collects the plugin descriptors which are found.
87       */
88      protected void customizeContainerConfiguration(ContainerConfiguration containerConfiguration) {
89          containerConfiguration.setAutoWiring(true).setClassPathScanning(PlexusConstants.SCANNING_INDEX);
90      }
91  
92      protected MavenExecutionRequest createMavenExecutionRequest(File pom) throws Exception {
93          MavenExecutionRequest request = new DefaultMavenExecutionRequest()
94                  .setPom(pom)
95                  .setProjectPresent(true)
96                  .setShowErrors(true)
97                  .setPluginGroups(Arrays.asList("org.apache.maven.plugins"))
98                  .setLocalRepository(getLocalRepository())
99                  .setRemoteRepositories(getRemoteRepositories())
100                 .setPluginArtifactRepositories(getPluginArtifactRepositories())
101                 .setGoals(Arrays.asList("package"));
102 
103         return request;
104     }
105 
106     // layer the creation of a project builder configuration with a request, but this will need to be
107     // a Maven subclass because we don't want to couple maven to the project builder which we need to
108     // separate.
109     protected MavenSession createMavenSession(File pom) throws Exception {
110         return createMavenSession(pom, new Properties());
111     }
112 
113     protected MavenSession createMavenSession(File pom, Properties executionProperties) throws Exception {
114         return createMavenSession(pom, executionProperties, false);
115     }
116 
117     protected MavenSession createMavenSession(File pom, Properties executionProperties, boolean includeModules)
118             throws Exception {
119         MavenExecutionRequest request = createMavenExecutionRequest(pom);
120 
121         ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest()
122                 .setLocalRepository(request.getLocalRepository())
123                 .setRemoteRepositories(request.getRemoteRepositories())
124                 .setPluginArtifactRepositories(request.getPluginArtifactRepositories())
125                 .setSystemProperties(executionProperties)
126                 .setUserProperties(new Properties());
127 
128         initRepoSession(configuration);
129 
130         List<MavenProject> projects = new ArrayList<>();
131 
132         if (pom != null) {
133             MavenProject project = projectBuilder.build(pom, configuration).getProject();
134 
135             projects.add(project);
136             if (includeModules) {
137                 for (String module : project.getModules()) {
138                     File modulePom = new File(pom.getParentFile(), module);
139                     if (modulePom.isDirectory()) {
140                         modulePom = new File(modulePom, "pom.xml");
141                     }
142                     projects.add(projectBuilder.build(modulePom, configuration).getProject());
143                 }
144             }
145         } else {
146             MavenProject project = createStubMavenProject();
147             project.setRemoteArtifactRepositories(request.getRemoteRepositories());
148             project.setPluginArtifactRepositories(request.getPluginArtifactRepositories());
149             projects.add(project);
150         }
151 
152         MavenSession session = new MavenSession(
153                 container, configuration.getRepositorySession(), request, new DefaultMavenExecutionResult());
154         session.setProjects(projects);
155         session.setAllProjects(session.getProjects());
156 
157         return session;
158     }
159 
160     protected void initRepoSession(ProjectBuildingRequest request) throws Exception {
161         File localRepoDir = new File(request.getLocalRepository().getBasedir());
162         LocalRepository localRepo = new LocalRepository(localRepoDir);
163         DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
164         session.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory().newInstance(session, localRepo));
165         request.setRepositorySession(session);
166     }
167 
168     protected MavenProject createStubMavenProject() {
169         Model model = new Model();
170         model.setGroupId("org.apache.maven.test");
171         model.setArtifactId("maven-test");
172         model.setVersion("1.0");
173         return new MavenProject(model);
174     }
175 
176     protected List<ArtifactRepository> getRemoteRepositories() throws InvalidRepositoryException {
177         File repoDir = new File(getBasedir(), "src/test/remote-repo").getAbsoluteFile();
178 
179         RepositoryPolicy policy = new RepositoryPolicy();
180         policy.setEnabled(true);
181         policy.setChecksumPolicy("ignore");
182         policy.setUpdatePolicy("always");
183 
184         Repository repository = new Repository();
185         repository.setId(RepositorySystem.DEFAULT_REMOTE_REPO_ID);
186         repository.setUrl("file://" + repoDir.toURI().getPath());
187         repository.setReleases(policy);
188         repository.setSnapshots(policy);
189 
190         return Arrays.asList(repositorySystem.buildArtifactRepositoryFromRepo(repository));
191     }
192 
193     protected List<ArtifactRepository> getPluginArtifactRepositories() throws InvalidRepositoryException {
194         return getRemoteRepositories();
195     }
196 
197     protected ArtifactRepository getLocalRepository() throws Exception {
198         File repoDir = new File(getBasedir(), "target/local-repo").getAbsoluteFile();
199 
200         return repositorySystem.createLocalRepository(null, repoDir);
201     }
202 
203     protected class ProjectBuilder {
204         private MavenProject project;
205 
206         public ProjectBuilder(MavenProject project) {
207             this.project = project;
208         }
209 
210         public ProjectBuilder(String groupId, String artifactId, String version) {
211             Model model = new Model();
212             model.setModelVersion("4.0.0");
213             model.setGroupId(groupId);
214             model.setArtifactId(artifactId);
215             model.setVersion(version);
216             model.setBuild(new Build());
217             project = new MavenProject(model);
218         }
219 
220         public ProjectBuilder setGroupId(String groupId) {
221             project.setGroupId(groupId);
222             return this;
223         }
224 
225         public ProjectBuilder setArtifactId(String artifactId) {
226             project.setArtifactId(artifactId);
227             return this;
228         }
229 
230         public ProjectBuilder setVersion(String version) {
231             project.setVersion(version);
232             return this;
233         }
234 
235         // Dependencies
236         //
237         public ProjectBuilder addDependency(String groupId, String artifactId, String version, String scope) {
238             return addDependency(groupId, artifactId, version, scope, (Exclusion) null);
239         }
240 
241         public ProjectBuilder addDependency(
242                 String groupId, String artifactId, String version, String scope, Exclusion exclusion) {
243             return addDependency(groupId, artifactId, version, scope, null, exclusion);
244         }
245 
246         public ProjectBuilder addDependency(
247                 String groupId, String artifactId, String version, String scope, String systemPath) {
248             return addDependency(groupId, artifactId, version, scope, systemPath, null);
249         }
250 
251         public ProjectBuilder addDependency(
252                 String groupId,
253                 String artifactId,
254                 String version,
255                 String scope,
256                 String systemPath,
257                 Exclusion exclusion) {
258             Dependency d = new Dependency();
259             d.setGroupId(groupId);
260             d.setArtifactId(artifactId);
261             d.setVersion(version);
262             d.setScope(scope);
263 
264             if (systemPath != null && scope.equals(Artifact.SCOPE_SYSTEM)) {
265                 d.setSystemPath(systemPath);
266             }
267 
268             if (exclusion != null) {
269                 d.addExclusion(exclusion);
270             }
271 
272             project.getDependencies().add(d);
273 
274             return this;
275         }
276 
277         // Plugins
278         //
279         public ProjectBuilder addPlugin(Plugin plugin) {
280             project.getBuildPlugins().add(plugin);
281             return this;
282         }
283 
284         public MavenProject get() {
285             return project;
286         }
287     }
288 }