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