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.plugin;
20  
21  import static org.codehaus.plexus.testing.PlexusExtension.getTestFile;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.io.File;
28  import java.util.ArrayList;
29  import java.util.Collections;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Properties;
33  import javax.inject.Inject;
34  import org.apache.maven.AbstractCoreMavenComponentTestCase;
35  import org.apache.maven.artifact.Artifact;
36  import org.apache.maven.artifact.ArtifactUtils;
37  import org.apache.maven.artifact.repository.ArtifactRepository;
38  import org.apache.maven.execution.DefaultMavenExecutionRequest;
39  import org.apache.maven.execution.DefaultMavenExecutionResult;
40  import org.apache.maven.execution.MavenExecutionRequest;
41  import org.apache.maven.execution.MavenSession;
42  import org.apache.maven.model.Build;
43  import org.apache.maven.model.Dependency;
44  import org.apache.maven.model.Model;
45  import org.apache.maven.plugin.descriptor.MojoDescriptor;
46  import org.apache.maven.plugin.descriptor.PluginDescriptor;
47  import org.apache.maven.project.DuplicateProjectException;
48  import org.apache.maven.project.MavenProject;
49  import org.apache.maven.repository.RepositorySystem;
50  import org.codehaus.plexus.MutablePlexusContainer;
51  import org.codehaus.plexus.PlexusContainer;
52  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
53  import org.codehaus.plexus.util.dag.CycleDetectedException;
54  import org.junit.jupiter.api.Test;
55  
56  /**
57   * @author Jason van Zyl
58   */
59  public class PluginParameterExpressionEvaluatorTest extends AbstractCoreMavenComponentTestCase {
60      private static final String FS = File.separator;
61  
62      @Inject
63      private RepositorySystem factory;
64  
65      @Test
66      public void testPluginDescriptorExpressionReference() throws Exception {
67          MojoExecution exec = newMojoExecution();
68  
69          MavenSession session = newMavenSession();
70  
71          Object result = new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin}");
72  
73          System.out.println("Result: " + result);
74  
75          assertSame(
76                  exec.getMojoDescriptor().getPluginDescriptor(),
77                  result,
78                  "${plugin} expression does not return plugin descriptor.");
79      }
80  
81      @Test
82      public void testPluginArtifactsExpressionReference() throws Exception {
83          MojoExecution exec = newMojoExecution();
84  
85          Artifact depArtifact = createArtifact("group", "artifact", "1");
86  
87          List<Artifact> deps = new ArrayList<>();
88          deps.add(depArtifact);
89  
90          exec.getMojoDescriptor().getPluginDescriptor().setArtifacts(deps);
91  
92          MavenSession session = newMavenSession();
93  
94          @SuppressWarnings("unchecked")
95          List<Artifact> depResults =
96                  (List<Artifact>) new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin.artifacts}");
97  
98          System.out.println("Result: " + depResults);
99  
100         assertNotNull(depResults);
101         assertEquals(1, depResults.size());
102         assertSame(depArtifact, depResults.get(0), "dependency artifact is wrong.");
103     }
104 
105     @Test
106     public void testPluginArtifactMapExpressionReference() throws Exception {
107         MojoExecution exec = newMojoExecution();
108 
109         Artifact depArtifact = createArtifact("group", "artifact", "1");
110 
111         List<Artifact> deps = new ArrayList<>();
112         deps.add(depArtifact);
113 
114         exec.getMojoDescriptor().getPluginDescriptor().setArtifacts(deps);
115 
116         MavenSession session = newMavenSession();
117 
118         @SuppressWarnings("unchecked")
119         Map<String, Artifact> depResults = (Map<String, Artifact>)
120                 new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin.artifactMap}");
121 
122         System.out.println("Result: " + depResults);
123 
124         assertNotNull(depResults);
125         assertEquals(1, depResults.size());
126         assertSame(
127                 depArtifact,
128                 depResults.get(ArtifactUtils.versionlessKey(depArtifact)),
129                 "dependency artifact is wrong.");
130     }
131 
132     @Test
133     public void testPluginArtifactIdExpressionReference() throws Exception {
134         MojoExecution exec = newMojoExecution();
135 
136         MavenSession session = newMavenSession();
137 
138         Object result = new PluginParameterExpressionEvaluator(session, exec).evaluate("${plugin.artifactId}");
139 
140         System.out.println("Result: " + result);
141 
142         assertSame(
143                 exec.getMojoDescriptor().getPluginDescriptor().getArtifactId(),
144                 result,
145                 "${plugin.artifactId} expression does not return plugin descriptor's artifactId.");
146     }
147 
148     @Test
149     public void testValueExtractionWithAPomValueContainingAPath() throws Exception {
150         String expected = getTestFile("target/test-classes/target/classes").getCanonicalPath();
151 
152         Build build = new Build();
153         build.setDirectory(expected.substring(0, expected.length() - "/classes".length()));
154 
155         Model model = new Model();
156         model.setBuild(build);
157 
158         MavenProject project = new MavenProject(model);
159         project.setFile(new File("pom.xml").getCanonicalFile());
160 
161         ExpressionEvaluator expressionEvaluator = createExpressionEvaluator(project, null, new Properties());
162 
163         Object value = expressionEvaluator.evaluate("${project.build.directory}/classes");
164         String actual = new File(value.toString()).getCanonicalPath();
165 
166         assertEquals(expected, actual);
167     }
168 
169     @Test
170     public void testEscapedVariablePassthrough() throws Exception {
171         String var = "${var}";
172 
173         Model model = new Model();
174         model.setVersion("1");
175 
176         MavenProject project = new MavenProject(model);
177 
178         ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
179 
180         Object value = ee.evaluate("$" + var);
181 
182         assertEquals(var, value);
183     }
184 
185     @Test
186     public void testEscapedVariablePassthroughInLargerExpression() throws Exception {
187         String var = "${var}";
188         String key = var + " with version: ${project.version}";
189 
190         Model model = new Model();
191         model.setVersion("1");
192 
193         MavenProject project = new MavenProject(model);
194 
195         ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
196 
197         Object value = ee.evaluate("$" + key);
198 
199         assertEquals("${var} with version: 1", value);
200     }
201 
202     @Test
203     public void testMultipleSubExpressionsInLargerExpression() throws Exception {
204         String key = "${project.artifactId} with version: ${project.version}";
205 
206         Model model = new Model();
207         model.setArtifactId("test");
208         model.setVersion("1");
209 
210         MavenProject project = new MavenProject(model);
211 
212         ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
213 
214         Object value = ee.evaluate(key);
215 
216         assertEquals("test with version: 1", value);
217     }
218 
219     @Test
220     public void testMissingPOMPropertyRefInLargerExpression() throws Exception {
221         String expr = "/path/to/someproject-${baseVersion}";
222 
223         MavenProject project = new MavenProject(new Model());
224 
225         ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
226 
227         Object value = ee.evaluate(expr);
228 
229         assertEquals(expr, value);
230     }
231 
232     @Test
233     public void testPOMPropertyExtractionWithMissingProject_WithDotNotation() throws Exception {
234         String key = "m2.name";
235         String checkValue = "value";
236 
237         Properties properties = new Properties();
238         properties.setProperty(key, checkValue);
239 
240         Model model = new Model();
241         model.setProperties(properties);
242 
243         MavenProject project = new MavenProject(model);
244 
245         ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties());
246 
247         Object value = ee.evaluate("${" + key + "}");
248 
249         assertEquals(checkValue, value);
250     }
251 
252     @Test
253     public void testBasedirExtractionWithMissingProject() throws Exception {
254         ExpressionEvaluator ee = createExpressionEvaluator(null, null, new Properties());
255 
256         Object value = ee.evaluate("${basedir}");
257 
258         assertEquals(System.getProperty("user.dir"), value);
259     }
260 
261     @Test
262     public void testValueExtractionFromSystemPropertiesWithMissingProject() throws Exception {
263         String sysprop = "PPEET_sysprop1";
264 
265         Properties executionProperties = new Properties();
266 
267         if (executionProperties.getProperty(sysprop) == null) {
268             executionProperties.setProperty(sysprop, "value");
269         }
270 
271         ExpressionEvaluator ee = createExpressionEvaluator(null, null, executionProperties);
272 
273         Object value = ee.evaluate("${" + sysprop + "}");
274 
275         assertEquals("value", value);
276     }
277 
278     @Test
279     public void testValueExtractionFromSystemPropertiesWithMissingProject_WithDotNotation() throws Exception {
280         String sysprop = "PPEET.sysprop2";
281 
282         Properties executionProperties = new Properties();
283 
284         if (executionProperties.getProperty(sysprop) == null) {
285             executionProperties.setProperty(sysprop, "value");
286         }
287 
288         ExpressionEvaluator ee = createExpressionEvaluator(null, null, executionProperties);
289 
290         Object value = ee.evaluate("${" + sysprop + "}");
291 
292         assertEquals("value", value);
293     }
294 
295     @SuppressWarnings("deprecation")
296     private static MavenSession createSession(PlexusContainer container, ArtifactRepository repo, Properties properties)
297             throws CycleDetectedException, DuplicateProjectException {
298         MavenExecutionRequest request = new DefaultMavenExecutionRequest()
299                 .setSystemProperties(properties)
300                 .setGoals(Collections.<String>emptyList())
301                 .setBaseDirectory(new File(""))
302                 .setLocalRepository(repo);
303 
304         return new MavenSession(
305                 container, request, new DefaultMavenExecutionResult(), Collections.<MavenProject>emptyList());
306     }
307 
308     @Test
309     public void testLocalRepositoryExtraction() throws Exception {
310         ExpressionEvaluator expressionEvaluator =
311                 createExpressionEvaluator(createDefaultProject(), null, new Properties());
312         Object value = expressionEvaluator.evaluate("${localRepository}");
313 
314         assertEquals("local", ((ArtifactRepository) value).getId());
315     }
316 
317     @Test
318     public void testTwoExpressions() throws Exception {
319         Build build = new Build();
320         build.setDirectory("expected-directory");
321         build.setFinalName("expected-finalName");
322 
323         Model model = new Model();
324         model.setBuild(build);
325 
326         ExpressionEvaluator expressionEvaluator =
327                 createExpressionEvaluator(new MavenProject(model), null, new Properties());
328 
329         Object value = expressionEvaluator.evaluate("${project.build.directory}" + FS + "${project.build.finalName}");
330 
331         assertEquals("expected-directory" + File.separatorChar + "expected-finalName", value);
332     }
333 
334     @Test
335     public void testShouldExtractPluginArtifacts() throws Exception {
336         PluginDescriptor pd = new PluginDescriptor();
337 
338         Artifact artifact = createArtifact("testGroup", "testArtifact", "1.0");
339 
340         pd.setArtifacts(Collections.singletonList(artifact));
341 
342         ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), pd, new Properties());
343 
344         Object value = ee.evaluate("${plugin.artifacts}");
345 
346         assertTrue(value instanceof List);
347 
348         @SuppressWarnings("unchecked")
349         List<Artifact> artifacts = (List<Artifact>) value;
350 
351         assertEquals(1, artifacts.size());
352 
353         Artifact result = artifacts.get(0);
354 
355         assertEquals("testGroup", result.getGroupId());
356     }
357 
358     private MavenProject createDefaultProject() {
359         return new MavenProject(new Model());
360     }
361 
362     private ExpressionEvaluator createExpressionEvaluator(
363             MavenProject project, PluginDescriptor pluginDescriptor, Properties executionProperties) throws Exception {
364         ArtifactRepository repo = factory.createDefaultLocalRepository();
365 
366         MutablePlexusContainer container = (MutablePlexusContainer) getContainer();
367         MavenSession session = createSession(container, repo, executionProperties);
368         session.setCurrentProject(project);
369 
370         MojoDescriptor mojo = new MojoDescriptor();
371         mojo.setPluginDescriptor(pluginDescriptor);
372         mojo.setGoal("goal");
373 
374         MojoExecution mojoExecution = new MojoExecution(mojo);
375 
376         return new PluginParameterExpressionEvaluator(session, mojoExecution);
377     }
378 
379     protected Artifact createArtifact(String groupId, String artifactId, String version) throws Exception {
380         Dependency dependency = new Dependency();
381         dependency.setGroupId(groupId);
382         dependency.setArtifactId(artifactId);
383         dependency.setVersion(version);
384         dependency.setType("jar");
385         dependency.setScope("compile");
386 
387         return factory.createDependencyArtifact(dependency);
388     }
389 
390     private MojoExecution newMojoExecution() {
391         PluginDescriptor pd = new PluginDescriptor();
392         pd.setArtifactId("my-plugin");
393         pd.setGroupId("org.myco.plugins");
394         pd.setVersion("1");
395 
396         MojoDescriptor md = new MojoDescriptor();
397         md.setPluginDescriptor(pd);
398 
399         pd.addComponentDescriptor(md);
400 
401         return new MojoExecution(md);
402     }
403 
404     private MavenSession newMavenSession() throws Exception {
405         return createMavenSession(null);
406     }
407 
408     @Override
409     protected String getProjectsDirectory() {
410         // TODO Auto-generated method stub
411         return null;
412     }
413 }