View Javadoc

1   package org.apache.maven.plugin;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.execution.MavenSession;
23  import org.apache.maven.plugin.descriptor.MojoDescriptor;
24  import org.apache.maven.plugin.descriptor.PluginDescriptor;
25  import org.apache.maven.project.MavenProject;
26  import org.apache.maven.project.path.PathTranslator;
27  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
28  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
29  import org.codehaus.plexus.logging.Logger;
30  import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
31  
32  import java.io.File;
33  import java.util.HashMap;
34  import java.util.Map;
35  import java.util.Properties;
36  
37  /**
38   * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
39   * @version $Id: PluginParameterExpressionEvaluator.java 565812 2007-08-14 15:33:44Z jdcasey $
40   * @todo belong in MavenSession, so it only gets created once?
41   */
42  public class PluginParameterExpressionEvaluator
43      implements ExpressionEvaluator
44  {
45      private static final Map BANNED_EXPRESSIONS;
46  
47      private static final Map DEPRECATED_EXPRESSIONS;
48  
49      static
50      {
51          Map deprecated = new HashMap();
52  
53          deprecated.put( "project.build.resources", "project.resources" );
54          deprecated.put( "project.build.testResources", "project.testResources" );
55  
56          DEPRECATED_EXPRESSIONS = deprecated;
57  
58          Map banned = new HashMap();
59  
60          BANNED_EXPRESSIONS = banned;
61      }
62  
63      private final PathTranslator pathTranslator;
64  
65      private final MavenSession context;
66  
67      private final Logger logger;
68  
69      private final MojoExecution mojoExecution;
70  
71      private final MavenProject project;
72  
73      private final String basedir;
74  
75      private final Properties properties;
76  
77      public PluginParameterExpressionEvaluator( MavenSession context,
78                                                 MojoExecution mojoExecution,
79                                                 PathTranslator pathTranslator,
80                                                 Logger logger,
81                                                 MavenProject project,
82                                                 Properties properties )
83      {
84          this.context = context;
85          this.mojoExecution = mojoExecution;
86          this.pathTranslator = pathTranslator;
87          this.logger = logger;
88          this.project = project;
89          this.properties = properties;
90  
91          String basedir = null;
92  
93          if ( project != null )
94          {
95              File projectFile = project.getFile();
96  
97              // this should always be the case for non-super POM instances...
98              if ( projectFile != null )
99              {
100                 basedir = projectFile.getParentFile().getAbsolutePath();
101             }
102         }
103 
104         if ( basedir == null )
105         {
106             basedir = System.getProperty( "user.dir" );
107         }
108 
109         this.basedir = basedir;
110     }
111 
112     public Object evaluate( String expr )
113         throws ExpressionEvaluationException
114     {
115         Object value = null;
116 
117         if ( expr == null )
118         {
119             return null;
120         }
121         
122         String expression = stripTokens( expr );
123         if ( expression.equals( expr ) )
124         {
125             int index = expr.indexOf( "${" );
126             if ( index >= 0 )
127             {
128                 int lastIndex = expr.indexOf( "}", index );
129                 if ( lastIndex >= 0 )
130                 {
131                     String retVal = expr.substring( 0, index );
132                     
133                     if ( index > 0 && expr.charAt( index - 1 ) == '$' )
134                     {
135                         retVal += expr.substring( index + 1, lastIndex + 1 );
136                     }
137                     else
138                     {
139                         retVal += evaluate( expr.substring( index, lastIndex + 1 ) );
140                     }
141                     
142                     retVal += evaluate( expr.substring( lastIndex + 1 ) );
143                     return retVal;
144                 }
145             }
146 
147             // Was not an expression
148             if ( expression.indexOf( "$$" ) > -1 )
149             {
150                 return expression.replaceAll( "\\$\\$", "\\$" );
151             }
152             else
153             {
154                 return expression;
155             }
156         }
157 
158         MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
159         if ( BANNED_EXPRESSIONS.containsKey( expression ) )
160         {
161             throw new ExpressionEvaluationException( "The parameter expression: \'" + expression +
162                 "\' used in mojo: \'" + mojoDescriptor.getGoal() + "\' is banned. Use \'" +
163                 BANNED_EXPRESSIONS.get( expression ) + "\' instead." );
164         }
165         else if ( DEPRECATED_EXPRESSIONS.containsKey( expression ) )
166         {
167             logger.warn( "The parameter expression: \'" + expression + "\' used in mojo: \'" +
168                 mojoDescriptor.getGoal() + "\' has been deprecated. Use \'" + DEPRECATED_EXPRESSIONS.get( expression ) +
169                 "\' instead." );
170         }
171 
172         if ( "localRepository".equals( expression ) )
173         {
174             value = context.getLocalRepository();
175         }
176         else if ( "session".equals( expression ) )
177         {
178             value = context;
179         }
180         else if ( "reactorProjects".equals( expression ) )
181         {
182             value = context.getSortedProjects();
183         }
184         else if ( "reports".equals( expression ) )
185         {
186             value = mojoExecution.getReports();
187         }
188         else if ("mojoExecution".equals(expression)) 
189         {
190         	value = mojoExecution;
191         }
192         else if ( "project".equals( expression ) )
193         {
194             value = project;
195         }
196         else if ( "executedProject".equals( expression ) )
197         {
198             value = project.getExecutionProject();
199         }
200         else if ( expression.startsWith( "project" ) )
201         {
202             try
203             {
204                 int pathSeparator = expression.indexOf( "/" );
205 
206                 if ( pathSeparator > 0 )
207                 {
208                     String pathExpression = expression.substring( 0, pathSeparator );
209                     value = ReflectionValueExtractor.evaluate( pathExpression, project );
210                     value = value + expression.substring( pathSeparator );
211                 }
212                 else
213                 {
214                     value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), project );
215                 }
216             }
217             catch ( Exception e )
218             {
219                 // TODO: don't catch exception
220                 throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
221                                                          e );
222             }
223         }
224         else if ( expression.startsWith( "plugin" ) )
225         {
226             try
227             {
228                 int pathSeparator = expression.indexOf( "/" );
229 
230                 PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
231 
232                 if ( pathSeparator > 0 )
233                 {
234                     String pathExpression = expression.substring( 1, pathSeparator );
235                     value = ReflectionValueExtractor.evaluate( pathExpression, pluginDescriptor );
236                     value = value + expression.substring( pathSeparator );
237                 }
238                 else
239                 {
240                     value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), pluginDescriptor );
241                 }
242             }
243             catch ( Exception e )
244             {
245                 // TODO: don't catch exception
246                 throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
247                                                          e );
248             }
249         }
250         else if ( "settings".equals( expression ) )
251         {
252             value = context.getSettings();
253         }
254         else if ( expression.startsWith( "settings" ) )
255         {
256             try
257             {
258                 int pathSeparator = expression.indexOf( "/" );
259 
260                 if ( pathSeparator > 0 )
261                 {
262                     String pathExpression = expression.substring( 1, pathSeparator );
263                     value = ReflectionValueExtractor.evaluate( pathExpression, context.getSettings() );
264                     value = value + expression.substring( pathSeparator );
265                 }
266                 else
267                 {
268                     value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), context.getSettings() );
269                 }
270             }
271             catch ( Exception e )
272             {
273                 // TODO: don't catch exception
274                 throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
275                                                          e );
276             }
277         }
278         else if ( "basedir".equals( expression ) )
279         {
280             value = basedir;
281         }
282         else if ( expression.startsWith( "basedir" ) )
283         {
284             int pathSeparator = expression.indexOf( "/" );
285 
286             if ( pathSeparator > 0 )
287             {
288                 value = basedir + expression.substring( pathSeparator );
289             }
290             else
291             {
292                 logger.error( "Got expression '" + expression + "' that was not recognised" );
293             }
294         }
295 
296         if ( value == null )
297         {
298             // Check POM-level properties before we default over to system properties.
299             if ( project != null && project.getProperties() != null )
300             {
301                 value = project.getProperties().getProperty( expression );
302             }
303 
304             if ( value == null && properties != null )
305             {
306                 // We will attempt to get nab a system property as a way to specify a
307                 // parameter to a plugins. My particular case here is allowing the surefire
308                 // plugin to run a single test so I want to specify that class on the cli
309                 // as a parameter.
310 
311                 value = properties.getProperty( expression );
312             }
313         }
314 
315         if ( value instanceof String )
316         {
317             // TODO: without #, this could just be an evaluate call...
318 
319             String val = (String) value;
320 
321             int exprStartDelimiter = val.indexOf( "${" );
322 
323             if ( exprStartDelimiter >= 0 )
324             {
325                 if ( exprStartDelimiter > 0 )
326                 {
327                     value = val.substring( 0, exprStartDelimiter ) + evaluate( val.substring( exprStartDelimiter ) );
328                 }
329                 else
330                 {
331                     value = evaluate( val.substring( exprStartDelimiter ) );
332                 }
333             }
334         }
335 
336         return value;
337     }
338 
339     private String stripTokens( String expr )
340     {
341         if ( expr.startsWith( "${" ) && expr.indexOf( "}" ) == expr.length() - 1 )
342         {
343             expr = expr.substring( 2, expr.length() - 1 );
344         }
345         return expr;
346     }
347 
348     public File alignToBaseDirectory( File file )
349     {
350         File basedir;
351 
352         if ( project != null && project.getFile() != null )
353         {
354             basedir = project.getFile().getParentFile();
355         }
356         else
357         {
358             basedir = new File( "." ).getAbsoluteFile().getParentFile();
359         }
360 
361         return new File( pathTranslator.alignToBaseDirectory( file.getPath(), basedir ) );
362     }
363 
364 }