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