View Javadoc

1   package org.apache.maven.plugin.resources;
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.model.Resource;
24  import org.apache.maven.plugin.AbstractMojo;
25  import org.apache.maven.plugin.MojoExecutionException;
26  import org.apache.maven.project.MavenProject;
27  import org.apache.maven.shared.filtering.MavenFilteringException;
28  import org.apache.maven.shared.filtering.MavenResourcesExecution;
29  import org.apache.maven.shared.filtering.MavenResourcesFiltering;
30  import org.codehaus.plexus.PlexusConstants;
31  import org.codehaus.plexus.PlexusContainer;
32  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
33  import org.codehaus.plexus.context.Context;
34  import org.codehaus.plexus.context.ContextException;
35  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
36  import org.codehaus.plexus.util.ReaderFactory;
37  import org.codehaus.plexus.util.StringUtils;
38  
39  import java.io.File;
40  import java.util.ArrayList;
41  import java.util.Collection;
42  import java.util.Collections;
43  import java.util.Iterator;
44  import java.util.LinkedHashSet;
45  import java.util.List;
46  
47  /**
48   * Copy resources for the main source code to the main output directory.
49   * Always uses the project.build.resources element to specify the resources to copy.
50   *
51   * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
52   * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
53   * @author Andreas Hoheneder
54   * @author William Ferguson
55   * @version $Id: ResourcesMojo.java 1059420 2011-01-15 22:10:12Z olamy $
56   * @goal resources
57   * @phase process-resources
58   * @threadSafe
59   * 
60   */
61  public class ResourcesMojo
62      extends AbstractMojo 
63      implements Contextualizable
64  {
65  
66      /**
67       * The character encoding scheme to be applied when filtering resources.
68       *
69       * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
70       */
71      protected String encoding;
72  
73      /**
74       * The output directory into which to copy the resources.
75       *
76       * @parameter default-value="${project.build.outputDirectory}"
77       * @required
78       */
79      private File outputDirectory;
80  
81      /**
82       * The list of resources we want to transfer.
83       *
84       * @parameter default-value="${project.resources}"
85       * @required
86       * @readonly
87       */
88      private List resources;
89  
90      /**
91       * @parameter default-value="${project}"
92       * @required
93       * @readonly
94       */
95      protected MavenProject project;
96  
97      /**
98       * The list of additional filter properties files to be used along with System and project
99       * properties, which would be used for the filtering.
100      * <br/>
101      * See also: {@link ResourcesMojo#filters}.
102      *
103      * @parameter default-value="${project.build.filters}"
104      * @readonly
105      * @since 2.4
106      */
107     protected List buildFilters;
108     
109     /**
110      * The list of extra filter properties files to be used along with System properties,
111      * project properties, and filter properties files specified in the POM build/filters section,
112      * which should be used for the filtering during the current mojo execution.
113      * <br/>
114      * Normally, these will be configured from a plugin's execution section, to provide a different
115      * set of filters for a particular execution. For instance, starting in Maven 2.2.0, you have the
116      * option of configuring executions with the id's <code>default-resources</code> and 
117      * <code>default-testResources</code> to supply different configurations for the two 
118      * different types of resources. By supplying <code>extraFilters</code> configurations, you
119      * can separate which filters are used for which type of resource.
120      *
121      * @parameter
122      */
123     protected List filters;
124     
125     /**
126      * If false, don't use the filters specified in the build/filters section of the POM when
127      * processing resources in this mojo execution.
128      * <br/>
129      * See also: {@link ResourcesMojo#buildFilters} and {@link ResourcesMojo#filters}
130      * @parameter default-value="true"
131      * @since 2.4
132      */
133     protected boolean useBuildFilters;
134     
135     /**
136      * 
137      * @component role="org.apache.maven.shared.filtering.MavenResourcesFiltering" role-hint="default"
138      * @required
139      */    
140     protected MavenResourcesFiltering mavenResourcesFiltering;    
141     
142     /**
143      * @parameter default-value="${session}"
144      * @readonly
145      * @required
146      */
147     protected MavenSession session;   
148     
149     /**
150      * Expression preceded with the String won't be interpolated 
151      * \${foo} will be replaced with ${foo}
152      * @parameter expression="${maven.resources.escapeString}"
153      * @since 2.3
154      */    
155     protected String escapeString;
156     
157     /**
158      * Overwrite existing files even if the destination files are newer.
159      * @parameter expression="${maven.resources.overwrite}" default-value="false"
160      * @since 2.3
161      */
162     private boolean overwrite;
163     
164     /**
165      * Copy any empty directories included in the Ressources.
166      * @parameter expression="${maven.resources.includeEmptyDirs}" default-value="false"
167      * @since 2.3
168      */    
169     protected boolean includeEmptyDirs;
170     
171     /**
172      * Additional file extensions to not apply filtering (already defined are : jpg, jpeg, gif, bmp, png)
173      * @parameter 
174      * @since 2.3
175      */
176     protected List nonFilteredFileExtensions;
177     
178     /**
179      * Whether to escape backslashes and colons in windows-style paths.
180      * @parameter expression="${maven.resources.escapeWindowsPaths}" default-value="true"
181      * @since 2.4
182      */
183     protected boolean escapeWindowsPaths;
184     
185     /**
186      * <p>
187      * Set of delimiters for expressions to filter within the resources. These delimiters are specified in the
188      * form 'beginToken*endToken'. If no '*' is given, the delimiter is assumed to be the same for start and end.
189      * </p><p>
190      * So, the default filtering delimiters might be specified as:
191      * </p>
192      * <pre>
193      * &lt;delimiters&gt;
194      *   &lt;delimiter&gt;${*}&lt/delimiter&gt;
195      *   &lt;delimiter&gt;@&lt/delimiter&gt;
196      * &lt;/delimiters&gt;
197      * </pre>
198      * <p>
199      * Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can).
200      * </p>
201      * @parameter
202      * @since 2.4
203      */
204     protected List delimiters;
205     
206     /**
207      * @parameter default-value="true"
208      * @since 2.4
209      */
210     protected boolean useDefaultDelimiters;
211     
212     /**
213      * <p>
214      * List of plexus components hint which implements {@link MavenResourcesFiltering#filterResources(MavenResourcesExecution)}.
215      * They will be executed after the resources copying/filtering.
216      * </p>
217      * @parameter
218      * @since 2.4
219      */
220     private List mavenFilteringHints;
221     
222     /**
223      * @since 2.4
224      */    
225     private PlexusContainer plexusContainer;
226     
227     /**
228      * @since 2.4
229      */     
230     private List mavenFilteringComponents = new ArrayList();
231     
232     /**
233      * stop searching endToken at the end of line
234      * @parameter expression="${maven.resources.supportMultiLineFiltering}" default-value="false"
235      * @since 2.5
236      */
237     private boolean supportMultiLineFiltering;
238     
239     public void contextualize( Context context )
240         throws ContextException
241     {
242         getLog().debug( "execute contextualize" );
243         plexusContainer = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
244     }
245 
246     public void execute()
247         throws MojoExecutionException
248     {
249         try
250         {
251             
252             if ( StringUtils.isEmpty( encoding ) && isFilteringEnabled( getResources() ) )
253             {
254                 getLog().warn(
255                                "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
256                                    + ", i.e. build is platform dependent!" );
257             }
258             
259             List filters = getCombinedFiltersList();
260 
261             MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution( getResources(), 
262                                                                                            getOutputDirectory(),
263                                                                                            project, encoding, filters,
264                                                                                            Collections.EMPTY_LIST,
265                                                                                            session );
266             
267             mavenResourcesExecution.setEscapeWindowsPaths( escapeWindowsPaths );
268             
269             // never include project build filters in this call, since we've already accounted for the POM build filters
270             // above, in getCombinedFiltersList().
271             mavenResourcesExecution.setInjectProjectBuildFilters( false );
272             
273             mavenResourcesExecution.setEscapeString( escapeString );
274             mavenResourcesExecution.setOverwrite( overwrite );
275             mavenResourcesExecution.setIncludeEmptyDirs( includeEmptyDirs );
276             mavenResourcesExecution.setSupportMultiLineFiltering( supportMultiLineFiltering );
277             
278             
279             
280             // if these are NOT set, just use the defaults, which are '${*}' and '@'.
281             if ( delimiters != null && !delimiters.isEmpty() )
282             {
283                 LinkedHashSet delims = new LinkedHashSet();
284                 if ( useDefaultDelimiters )
285                 {
286                     delims.addAll( mavenResourcesExecution.getDelimiters() );
287                 }
288                 
289                 for ( Iterator dIt = delimiters.iterator(); dIt.hasNext(); )
290                 {
291                     String delim = (String) dIt.next();
292                     if ( delim == null )
293                     {
294                         // FIXME: ${filter:*} could also trigger this condition. Need a better long-term solution.
295                         delims.add( "${*}" );
296                     }
297                     else
298                     {
299                         delims.add( delim );
300                     }
301                 }
302                 
303                 mavenResourcesExecution.setDelimiters( delims );
304             }
305             
306             if ( nonFilteredFileExtensions != null )
307             {
308                 mavenResourcesExecution.setNonFilteredFileExtensions( nonFilteredFileExtensions );
309             }
310             mavenResourcesFiltering.filterResources( mavenResourcesExecution );
311             
312             executeUserFilterComponents( mavenResourcesExecution );
313         }
314         catch ( MavenFilteringException e )
315         {
316             throw new MojoExecutionException( e.getMessage(), e );
317         }
318     }
319     
320     /**
321      * @since 2.5
322      */
323     protected void executeUserFilterComponents( MavenResourcesExecution mavenResourcesExecution )
324         throws MojoExecutionException, MavenFilteringException
325     {
326 
327         if ( mavenFilteringHints != null )
328         {
329             for ( Iterator ite = mavenFilteringHints.iterator(); ite.hasNext(); )
330             {
331                 String hint = (String) ite.next();
332                 try
333                 {
334                     mavenFilteringComponents
335                         .add( plexusContainer.lookup( MavenResourcesFiltering.class.getName(), hint ) );
336                 }
337                 catch ( ComponentLookupException e )
338                 {
339                     throw new MojoExecutionException( e.getMessage(), e );
340                 }
341             }
342         }
343         else
344         {
345             getLog().debug( "no use filter components" );
346         }
347 
348         if ( mavenFilteringComponents != null && !mavenFilteringComponents.isEmpty() )
349         {
350             getLog().debug( "execute user filters" );
351             for ( Iterator ite = mavenFilteringComponents.iterator(); ite.hasNext(); )
352             {
353                 MavenResourcesFiltering filter = (MavenResourcesFiltering) ite.next();
354                 filter.filterResources( mavenResourcesExecution );
355             }
356         }
357     }
358     
359     protected List getCombinedFiltersList()
360     {
361         if ( filters == null || filters.isEmpty() )
362         {
363             return useBuildFilters ? buildFilters : null;
364         }
365         else
366         {
367             List result = new ArrayList();
368             
369             if ( useBuildFilters && buildFilters != null && !buildFilters.isEmpty() )
370             {
371                 result.addAll( buildFilters );
372             }
373             
374             result.addAll( filters );
375             
376             return result;
377         }
378     }
379 
380     /**
381      * Determines whether filtering has been enabled for any resource.
382      * 
383      * @param resources The set of resources to check for filtering, may be <code>null</code>.
384      * @return <code>true</code> if at least one resource uses filtering, <code>false</code> otherwise.
385      */
386     private boolean isFilteringEnabled( Collection resources )
387     {
388         if ( resources != null )
389         {
390             for ( Iterator i = resources.iterator(); i.hasNext(); )
391             {
392                 Resource resource = (Resource) i.next();
393                 if ( resource.isFiltering() )
394                 {
395                     return true;
396                 }
397             }
398         }
399         return false;
400     }
401 
402     public List getResources()
403     {
404         return resources;
405     }
406 
407     public void setResources( List resources )
408     {
409         this.resources = resources;
410     }
411 
412     public File getOutputDirectory()
413     {
414         return outputDirectory;
415     }
416 
417     public void setOutputDirectory( File outputDirectory )
418     {
419         this.outputDirectory = outputDirectory;
420     }
421 
422     public boolean isOverwrite()
423     {
424         return overwrite;
425     }
426 
427     public void setOverwrite( boolean overwrite )
428     {
429         this.overwrite = overwrite;
430     }
431 
432     public boolean isIncludeEmptyDirs()
433     {
434         return includeEmptyDirs;
435     }
436 
437     public void setIncludeEmptyDirs( boolean includeEmptyDirs )
438     {
439         this.includeEmptyDirs = includeEmptyDirs;
440     }
441 
442     public List getFilters()
443     {
444         return filters;
445     }
446 
447     public void setFilters( List filters )
448     {
449         this.filters = filters;
450     }
451 
452     public List getDelimiters()
453     {
454         return delimiters;
455     }
456 
457     public void setDelimiters( List delimiters )
458     {
459         this.delimiters = delimiters;
460     }
461 
462     public boolean isUseDefaultDelimiters()
463     {
464         return useDefaultDelimiters;
465     }
466 
467     public void setUseDefaultDelimiters( boolean useDefaultDelimiters )
468     {
469         this.useDefaultDelimiters = useDefaultDelimiters;
470     }
471 
472 }