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