001package org.apache.maven.plugin;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.List;
026import java.util.Map;
027import java.util.Properties;
028
029import org.apache.maven.AbstractCoreMavenComponentTestCase;
030import org.apache.maven.artifact.Artifact;
031import org.apache.maven.artifact.ArtifactUtils;
032import org.apache.maven.artifact.repository.ArtifactRepository;
033import org.apache.maven.execution.DefaultMavenExecutionRequest;
034import org.apache.maven.execution.DefaultMavenExecutionResult;
035import org.apache.maven.execution.MavenExecutionRequest;
036import org.apache.maven.execution.MavenSession;
037import org.apache.maven.model.Build;
038import org.apache.maven.model.Dependency;
039import org.apache.maven.model.Model;
040import org.apache.maven.plugin.descriptor.MojoDescriptor;
041import org.apache.maven.plugin.descriptor.PluginDescriptor;
042import org.apache.maven.project.DuplicateProjectException;
043import org.apache.maven.project.MavenProject;
044import org.apache.maven.repository.RepositorySystem;
045import org.codehaus.plexus.MutablePlexusContainer;
046import org.codehaus.plexus.PlexusContainer;
047import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
048import org.codehaus.plexus.util.dag.CycleDetectedException;
049
050/**
051 * @author Jason van Zyl
052 */
053public class PluginParameterExpressionEvaluatorTest
054    extends AbstractCoreMavenComponentTestCase
055{
056    private static final String FS = System.getProperty( "file.separator" );
057
058    private RepositorySystem factory;
059
060    public void setUp()
061        throws Exception
062    {
063        super.setUp();
064        factory = lookup( RepositorySystem.class );
065    }
066
067    @Override
068    protected void tearDown()
069        throws Exception
070    {
071        factory = null;
072        super.tearDown();
073    }
074
075    public void testPluginDescriptorExpressionReference()
076        throws Exception
077    {
078        MojoExecution exec = newMojoExecution();
079
080        MavenSession session = newMavenSession();
081
082        Object result = new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin}" );
083
084        System.out.println( "Result: " + result );
085
086        assertSame( "${plugin} expression does not return plugin descriptor.",
087                    exec.getMojoDescriptor().getPluginDescriptor(),
088                    result );
089    }
090
091    public void testPluginArtifactsExpressionReference()
092        throws Exception
093    {
094        MojoExecution exec = newMojoExecution();
095
096        Artifact depArtifact = createArtifact( "group", "artifact", "1" );
097
098        List<Artifact> deps = new ArrayList<Artifact>();
099        deps.add( depArtifact );
100
101        exec.getMojoDescriptor().getPluginDescriptor().setArtifacts( deps );
102
103        MavenSession session = newMavenSession();
104
105        @SuppressWarnings( "unchecked" )
106        List<Artifact> depResults =
107            (List<Artifact>) new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin.artifacts}" );
108
109        System.out.println( "Result: " + depResults );
110
111        assertNotNull( depResults );
112        assertEquals( 1, depResults.size() );
113        assertSame( "dependency artifact is wrong.", depArtifact, depResults.get( 0 ) );
114    }
115
116    public void testPluginArtifactMapExpressionReference()
117        throws Exception
118    {
119        MojoExecution exec = newMojoExecution();
120
121        Artifact depArtifact = createArtifact( "group", "artifact", "1" );
122
123        List<Artifact> deps = new ArrayList<Artifact>();
124        deps.add( depArtifact );
125
126        exec.getMojoDescriptor().getPluginDescriptor().setArtifacts( deps );
127
128        MavenSession session = newMavenSession();
129
130        @SuppressWarnings( "unchecked" )
131        Map<String, Artifact> depResults =
132            (Map<String, Artifact>) new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin.artifactMap}" );
133
134        System.out.println( "Result: " + depResults );
135
136        assertNotNull( depResults );
137        assertEquals( 1, depResults.size() );
138        assertSame( "dependency artifact is wrong.",
139                    depArtifact,
140                    depResults.get( ArtifactUtils.versionlessKey( depArtifact ) ) );
141    }
142
143    public void testPluginArtifactIdExpressionReference()
144        throws Exception
145    {
146        MojoExecution exec = newMojoExecution();
147
148        MavenSession session = newMavenSession();
149
150        Object result = new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin.artifactId}" );
151
152        System.out.println( "Result: " + result );
153
154        assertSame( "${plugin.artifactId} expression does not return plugin descriptor's artifactId.",
155                    exec.getMojoDescriptor().getPluginDescriptor().getArtifactId(),
156                    result );
157    }
158
159    public void testValueExtractionWithAPomValueContainingAPath()
160        throws Exception
161    {
162        String expected = getTestFile( "target/test-classes/target/classes" ).getCanonicalPath();
163
164        Build build = new Build();
165        build.setDirectory( expected.substring( 0, expected.length() - "/classes".length() ) );
166
167        Model model = new Model();
168        model.setBuild( build );
169
170        MavenProject project = new MavenProject( model );
171        project.setFile( new File( "pom.xml" ).getCanonicalFile() );
172
173        ExpressionEvaluator expressionEvaluator = createExpressionEvaluator( project, null, new Properties() );
174
175        Object value = expressionEvaluator.evaluate( "${project.build.directory}/classes" );
176        String actual = new File( value.toString() ).getCanonicalPath();
177
178        assertEquals( expected, actual );
179    }
180
181    public void testEscapedVariablePassthrough()
182        throws Exception
183    {
184        String var = "${var}";
185
186        Model model = new Model();
187        model.setVersion( "1" );
188
189        MavenProject project = new MavenProject( model );
190
191        ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
192
193        Object value = ee.evaluate( "$" + var );
194
195        assertEquals( var, value );
196    }
197
198    public void testEscapedVariablePassthroughInLargerExpression()
199        throws Exception
200    {
201        String var = "${var}";
202        String key = var + " with version: ${project.version}";
203
204        Model model = new Model();
205        model.setVersion( "1" );
206
207        MavenProject project = new MavenProject( model );
208
209        ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
210
211        Object value = ee.evaluate( "$" + key );
212
213        assertEquals( "${var} with version: 1", value );
214    }
215
216    public void testMultipleSubExpressionsInLargerExpression()
217        throws Exception
218    {
219        String key = "${project.artifactId} with version: ${project.version}";
220
221        Model model = new Model();
222        model.setArtifactId( "test" );
223        model.setVersion( "1" );
224
225        MavenProject project = new MavenProject( model );
226
227        ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
228
229        Object value = ee.evaluate( key );
230
231        assertEquals( "test with version: 1", value );
232    }
233
234    public void testMissingPOMPropertyRefInLargerExpression()
235        throws Exception
236    {
237        String expr = "/path/to/someproject-${baseVersion}";
238
239        MavenProject project = new MavenProject( new Model() );
240
241        ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
242
243        Object value = ee.evaluate( expr );
244
245        assertEquals( expr, value );
246    }
247
248    public void testPOMPropertyExtractionWithMissingProject_WithDotNotation()
249        throws Exception
250    {
251        String key = "m2.name";
252        String checkValue = "value";
253
254        Properties properties = new Properties();
255        properties.setProperty( key, checkValue );
256
257        Model model = new Model();
258        model.setProperties( properties );
259
260        MavenProject project = new MavenProject( model );
261
262        ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
263
264        Object value = ee.evaluate( "${" + key + "}" );
265
266        assertEquals( checkValue, value );
267    }
268
269    public void testBasedirExtractionWithMissingProject()
270        throws Exception
271    {
272        ExpressionEvaluator ee = createExpressionEvaluator( null, null, new Properties() );
273
274        Object value = ee.evaluate( "${basedir}" );
275
276        assertEquals( System.getProperty( "user.dir" ), value );
277    }
278
279    public void testValueExtractionFromSystemPropertiesWithMissingProject()
280        throws Exception
281    {
282        String sysprop = "PPEET_sysprop1";
283
284        Properties executionProperties = new Properties();
285
286        if ( executionProperties.getProperty( sysprop ) == null )
287        {
288            executionProperties.setProperty( sysprop, "value" );
289        }
290
291        ExpressionEvaluator ee = createExpressionEvaluator( null, null, executionProperties );
292
293        Object value = ee.evaluate( "${" + sysprop + "}" );
294
295        assertEquals( "value", value );
296    }
297
298    public void testValueExtractionFromSystemPropertiesWithMissingProject_WithDotNotation()
299        throws Exception
300    {
301        String sysprop = "PPEET.sysprop2";
302
303        Properties executionProperties = new Properties();
304
305        if ( executionProperties.getProperty( sysprop ) == null )
306        {
307            executionProperties.setProperty( sysprop, "value" );
308        }
309
310        ExpressionEvaluator ee = createExpressionEvaluator( null, null, executionProperties );
311
312        Object value = ee.evaluate( "${" + sysprop + "}" );
313
314        assertEquals( "value", value );
315    }
316
317    @SuppressWarnings( "deprecation" )
318    private static MavenSession createSession( PlexusContainer container, ArtifactRepository repo, Properties properties )
319        throws CycleDetectedException, DuplicateProjectException
320    {
321        MavenExecutionRequest request = new DefaultMavenExecutionRequest()
322            .setSystemProperties( properties )
323            .setGoals( Collections.<String>emptyList() )
324            .setBaseDirectory( new File( "" ) )
325            .setLocalRepository( repo );
326
327        return new MavenSession( container, request, new DefaultMavenExecutionResult(), Collections.<MavenProject>emptyList()  );
328    }
329
330    public void testLocalRepositoryExtraction()
331        throws Exception
332    {
333        ExpressionEvaluator expressionEvaluator =
334            createExpressionEvaluator( createDefaultProject(), null, new Properties() );
335        Object value = expressionEvaluator.evaluate( "${localRepository}" );
336
337        assertEquals( "local", ( (ArtifactRepository) value ).getId() );
338    }
339
340    public void testTwoExpressions()
341        throws Exception
342    {
343        Build build = new Build();
344        build.setDirectory( "expected-directory" );
345        build.setFinalName( "expected-finalName" );
346
347        Model model = new Model();
348        model.setBuild( build );
349
350        ExpressionEvaluator expressionEvaluator =
351            createExpressionEvaluator( new MavenProject( model ), null, new Properties() );
352
353        Object value = expressionEvaluator.evaluate( "${project.build.directory}" + FS + "${project.build.finalName}" );
354
355        assertEquals( "expected-directory" + File.separatorChar + "expected-finalName", value );
356    }
357
358    public void testShouldExtractPluginArtifacts()
359        throws Exception
360    {
361        PluginDescriptor pd = new PluginDescriptor();
362
363        Artifact artifact = createArtifact( "testGroup", "testArtifact", "1.0" );
364
365        pd.setArtifacts( Collections.singletonList( artifact ) );
366
367        ExpressionEvaluator ee = createExpressionEvaluator( createDefaultProject(), pd, new Properties() );
368
369        Object value = ee.evaluate( "${plugin.artifacts}" );
370
371        assertTrue( value instanceof List );
372
373        @SuppressWarnings( "unchecked" )
374        List<Artifact> artifacts = (List<Artifact>) value;
375
376        assertEquals( 1, artifacts.size() );
377
378        Artifact result = artifacts.get( 0 );
379
380        assertEquals( "testGroup", result.getGroupId() );
381    }
382
383    private MavenProject createDefaultProject()
384    {
385        return new MavenProject( new Model() );
386    }
387
388    private ExpressionEvaluator createExpressionEvaluator( MavenProject project, PluginDescriptor pluginDescriptor, Properties executionProperties )
389        throws Exception
390    {
391        ArtifactRepository repo = factory.createDefaultLocalRepository();
392
393        MutablePlexusContainer container = (MutablePlexusContainer) getContainer();
394        MavenSession session = createSession( container, repo, executionProperties );
395        session.setCurrentProject( project );
396
397        MojoDescriptor mojo = new MojoDescriptor();
398        mojo.setPluginDescriptor( pluginDescriptor );
399        mojo.setGoal( "goal" );
400
401        MojoExecution mojoExecution = new MojoExecution( mojo );
402
403        return new PluginParameterExpressionEvaluator( session, mojoExecution );
404    }
405
406    protected Artifact createArtifact( String groupId, String artifactId, String version )
407        throws Exception
408    {
409        Dependency dependency = new Dependency();
410        dependency.setGroupId( groupId );
411        dependency.setArtifactId( artifactId );
412        dependency.setVersion( version );
413        dependency.setType( "jar" );
414        dependency.setScope( "compile" );
415
416        return factory.createDependencyArtifact( dependency );
417    }
418
419    private MojoExecution newMojoExecution()
420    {
421        PluginDescriptor pd = new PluginDescriptor();
422        pd.setArtifactId( "my-plugin" );
423        pd.setGroupId( "org.myco.plugins" );
424        pd.setVersion( "1" );
425
426        MojoDescriptor md = new MojoDescriptor();
427        md.setPluginDescriptor( pd );
428
429        pd.addComponentDescriptor( md );
430
431        return new MojoExecution( md );
432    }
433
434    private MavenSession newMavenSession()
435        throws Exception
436    {
437        return createMavenSession( null );
438    }
439
440    @Override
441    protected String getProjectsDirectory()
442    {
443        // TODO Auto-generated method stub
444        return null;
445    }
446
447}