1 package org.apache.maven.shared.filtering;
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 java.io.File;
23 import java.io.Reader;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.maven.execution.MavenSession;
28 import org.apache.maven.model.Resource;
29 import org.apache.maven.project.MavenProject;
30 import org.apache.maven.shared.utils.io.FileUtils;
31 import org.apache.maven.shared.utils.io.FileUtils.FilterWrapper;
32 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
33 import org.codehaus.plexus.interpolation.ValueSource;
34
35 /**
36 * A bean to configure a resources filtering execution.
37 *
38 * @author Olivier Lamy
39 */
40 public class MavenResourcesExecution
41 extends AbstractMavenFilteringRequest
42 {
43
44 private List<Resource> resources;
45
46 private File outputDirectory;
47
48 private List<String> nonFilteredFileExtensions;
49
50 private List<FileUtils.FilterWrapper> filterWrappers;
51
52 private File resourcesBaseDirectory;
53
54 private boolean useDefaultFilterWrappers = false;
55
56 private boolean filterFilenames = false;
57
58 private String encoding;
59
60 /**
61 * @since 3.2.0
62 */
63 private String propertiesEncoding;
64
65 /**
66 * By default files like {@code .gitignore}, {@code .cvsignore} etc. are excluded which means they will not being
67 * copied. If you need them for a particular reason you can do that by settings this to {@code false}. This means
68 * all files like the following will be copied.
69 * <ul>
70 * <li>Misc: **/*~, **/#*#, **/.#*, **/%*%, **/._*</li>
71 * <li>CVS: **/CVS, **/CVS/**, **/.cvsignore</li>
72 * <li>RCS: **/RCS, **/RCS/**</li>
73 * <li>SCCS: **/SCCS, **/SCCS/**</li>
74 * <li>VSSercer: **/vssver.scc</li>
75 * <li>MKS: **/project.pj</li>
76 * <li>SVN: **/.svn, **/.svn/**</li>
77 * <li>GNU: **/.arch-ids, **/.arch-ids/**</li>
78 * <li>Bazaar: **/.bzr, **/.bzr/**</li>
79 * <li>SurroundSCM: **/.MySCMServerInfo</li>
80 * <li>Mac: **/.DS_Store</li>
81 * <li>Serena Dimension: **/.metadata, **/.metadata/**</li>
82 * <li>Mercurial: **/.hg, **/.hg/**, **/.hgignore,</li>
83 * <li>GIT: **/.git, **/.gitignore, **/.gitattributes, **/.git/**</li>
84 * <li>Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet,
85 * **/ChangeSet/**</li>
86 * <li>Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo,
87 * **/.darcsrepo/****/-darcs-backup*, **/.darcs-temp-mail
88 * </ul>
89 *
90 * @since 3.1.0
91 */
92 private boolean addDefaultExcludes = true;
93
94 /**
95 * Overwrite existing files even if the destination files are newer. <code>false</code> by default.
96 *
97 * @since 1.0-beta-2
98 */
99 private boolean overwrite = false;
100
101 /**
102 * Copy any empty directories included in the Resources.
103 *
104 * @since 1.0-beta-2
105 */
106 private boolean includeEmptyDirs = false;
107
108 /**
109 * Do not stop trying to filter tokens when reaching EOL.
110 *
111 * @since 1.0
112 */
113 private boolean supportMultiLineFiltering;
114
115 /**
116 * Do nothing.
117 */
118 public MavenResourcesExecution()
119 {
120 // no op
121 }
122
123 /**
124 * As we use a Maven project <code>useDefaultFilterWrappers</code> will be set to <code>true</code>. The
125 * {@code useDefaultExcludes} is set to {@code true}.
126 *
127 * @param resources The list of resources.
128 * @param outputDirectory The output directory.
129 * @param mavenProject The maven project.
130 * @param encoding The given encoding.
131 * @param fileFilters The file filters.
132 * @param nonFilteredFileExtensions The extensions which should not being filtered.
133 * @param mavenSession The maven session.
134 */
135 public MavenResourcesExecution( List<Resource> resources, File outputDirectory, MavenProject mavenProject,
136 String encoding, List<String> fileFilters, List<String> nonFilteredFileExtensions,
137 MavenSession mavenSession )
138 {
139 super( mavenProject, fileFilters, mavenSession );
140 this.encoding = encoding;
141 this.resources = resources;
142 this.outputDirectory = outputDirectory;
143 this.nonFilteredFileExtensions = nonFilteredFileExtensions;
144 this.useDefaultFilterWrappers = true;
145 this.addDefaultExcludes = true;
146 this.resourcesBaseDirectory = mavenProject.getBasedir();
147 }
148
149 /**
150 * @param resources The list of resources.
151 * @param outputDirectory The output directory.
152 * @param encoding The given encoding.
153 * @param filterWrappers The list of filter wrappers.
154 * @param resourcesBaseDirectory The resources base directory.
155 * @param nonFilteredFileExtensions The list of extensions which should not being filtered.
156 */
157 public MavenResourcesExecution( List<Resource> resources, File outputDirectory, String encoding,
158 List<FileUtils.FilterWrapper> filterWrappers, File resourcesBaseDirectory,
159 List<String> nonFilteredFileExtensions )
160 {
161 this();
162 this.resources = resources;
163 this.outputDirectory = outputDirectory;
164 this.filterWrappers = filterWrappers;
165 this.nonFilteredFileExtensions = nonFilteredFileExtensions;
166 this.resourcesBaseDirectory = resourcesBaseDirectory;
167 this.useDefaultFilterWrappers = false;
168 setEncoding( encoding );
169 }
170
171 /**
172 * Return the encoding.
173 *
174 * @return Current encoding.
175 */
176 public String getEncoding()
177 {
178 return encoding;
179 }
180
181 /**
182 * Set the value for encoding.
183 *
184 * @param encoding Give the new value for encoding.
185 */
186 public void setEncoding( String encoding )
187 {
188 this.encoding = encoding;
189 }
190
191 /**
192 * Return the encoding of properties files.
193 *
194 * @return Current encoding of properties files.
195 * @since 3.2.0
196 */
197 public String getPropertiesEncoding()
198 {
199 return propertiesEncoding;
200 }
201
202 /**
203 * Set the value for encoding of properties files.
204 *
205 * @param propertiesEncoding Give the new value for encoding of properties files.
206 * @since 3.2.0
207 */
208 public void setPropertiesEncoding( String propertiesEncoding )
209 {
210 this.propertiesEncoding = propertiesEncoding;
211 }
212
213 /**
214 * @return List of {@link org.apache.maven.model.Resource}
215 */
216 public List<Resource> getResources()
217 {
218 return resources;
219 }
220
221 /**
222 * @param resources List of {@link org.apache.maven.model.Resource}
223 */
224 public void setResources( List<Resource> resources )
225 {
226 this.resources = resources;
227 }
228
229 /**
230 * @return The output directory.
231 */
232 public File getOutputDirectory()
233 {
234 return outputDirectory;
235 }
236
237 /**
238 * @param outputDirectory The output directory.
239 */
240 public void setOutputDirectory( File outputDirectory )
241 {
242 this.outputDirectory = outputDirectory;
243 }
244
245 /**
246 * @return List of {@link String} file extensions not to filter
247 */
248 public List<String> getNonFilteredFileExtensions()
249 {
250 return nonFilteredFileExtensions;
251 }
252
253 /**
254 * @param nonFilteredFileExtensions List of {@link String} file extensions to not filter
255 */
256 public void setNonFilteredFileExtensions( List<String> nonFilteredFileExtensions )
257 {
258 this.nonFilteredFileExtensions = nonFilteredFileExtensions;
259 }
260
261 /**
262 * @return List of {@link FileUtils.FilterWrapper}
263 */
264 public List<FileUtils.FilterWrapper> getFilterWrappers()
265 {
266 return filterWrappers;
267 }
268
269 /**
270 * @param filterWrappers List of {@link FileUtils.FilterWrapper}
271 */
272 public void setFilterWrappers( List<FileUtils.FilterWrapper> filterWrappers )
273 {
274 this.filterWrappers = filterWrappers;
275 }
276
277 /**
278 * @param filterWrapper The filter wrapper which should be added.
279 */
280 public void addFilterWrapper( FilterWrapper filterWrapper )
281 {
282 if ( this.filterWrappers == null )
283 {
284 this.filterWrappers = new ArrayList<>();
285 }
286 this.filterWrappers.add( filterWrapper );
287 }
288
289 /**
290 * @param valueSource {@link ValueSource}
291 * @param startExp start token like <code>${</code>
292 * @param endExp endToken <code>}</code>
293 * @param escapeString The escape string.
294 * @param multiLineFiltering do we support or use filtering on multi lines with start and endtoken on multi lines
295 * @since 1.0
296 */
297 public void addFilerWrapperWithEscaping( final ValueSource valueSource, final String startExp, final String endExp,
298 final String escapeString, final boolean multiLineFiltering )
299 {
300 addFilterWrapper( new FileUtils.FilterWrapper()
301 {
302 @Override
303 public Reader getReader( Reader reader )
304 {
305 StringSearchInterpolator propertiesInterpolator = new StringSearchInterpolator( startExp, endExp );
306 propertiesInterpolator.addValueSource( valueSource );
307 propertiesInterpolator.setEscapeString( escapeString );
308 InterpolatorFilterReaderLineEnding interpolatorFilterReader =
309 new InterpolatorFilterReaderLineEnding( reader, propertiesInterpolator, startExp, endExp,
310 multiLineFiltering );
311 interpolatorFilterReader.setInterpolateWithPrefixPattern( false );
312 return interpolatorFilterReader;
313 }
314 } );
315 }
316
317 /**
318 * @return The resource base directory.
319 */
320 public File getResourcesBaseDirectory()
321 {
322 return resourcesBaseDirectory;
323 }
324
325 /**
326 * @param resourcesBaseDirectory Set the resource base directory.
327 */
328 public void setResourcesBaseDirectory( File resourcesBaseDirectory )
329 {
330 this.resourcesBaseDirectory = resourcesBaseDirectory;
331 }
332
333 /**
334 * @return use default filter wrapper
335 */
336 public boolean isUseDefaultFilterWrappers()
337 {
338 return useDefaultFilterWrappers;
339 }
340
341 /**
342 * @param useDefaultFilterWrappers {@link #useDefaultFilterWrappers}
343 */
344 public void setUseDefaultFilterWrappers( boolean useDefaultFilterWrappers )
345 {
346 this.useDefaultFilterWrappers = useDefaultFilterWrappers;
347 }
348
349 /**
350 * @return add the default excludes.
351 */
352 public boolean isAddDefaultExcludes()
353 {
354 return addDefaultExcludes;
355 }
356
357 /**
358 * @param addDefaultExcludes {@link #addDefaultExcludes}
359 */
360 public void setAddDefaultExcludes( boolean addDefaultExcludes )
361 {
362 this.addDefaultExcludes = addDefaultExcludes;
363 }
364
365 /**
366 * Overwrite existing files even if the destination files are newer.
367 *
368 * @return {@link #overwrite}
369 * @since 1.0-beta-2
370 */
371 public boolean isOverwrite()
372 {
373 return overwrite;
374 }
375
376 /**
377 * Overwrite existing files even if the destination files are newer.
378 *
379 * @param overwrite overwrite true or false.
380 * @since 1.0-beta-2
381 */
382 public void setOverwrite( boolean overwrite )
383 {
384 this.overwrite = overwrite;
385 }
386
387 /**
388 * Copy any empty directories included in the Resources.
389 *
390 * @return {@link #includeEmptyDirs}
391 * @since 1.0-beta-2
392 */
393 public boolean isIncludeEmptyDirs()
394 {
395 return includeEmptyDirs;
396 }
397
398 /**
399 * Copy any empty directories included in the Resources.
400 *
401 * @param includeEmptyDirs {@code true} to include empty directories, otherwise {@code false}.
402 * @since 1.0-beta-2
403 */
404 public void setIncludeEmptyDirs( boolean includeEmptyDirs )
405 {
406 this.includeEmptyDirs = includeEmptyDirs;
407 }
408
409 /**
410 * @return {@code true} if filenames are filtered, otherwise {@code false}
411 * @since 1.2
412 */
413 public boolean isFilterFilenames()
414 {
415 return filterFilenames;
416 }
417
418 /**
419 * @param filterFilenames {@code true} if filenames should be filtered, otherwise {@code false}
420 * @since 1.2
421 */
422 public void setFilterFilenames( boolean filterFilenames )
423 {
424 this.filterFilenames = filterFilenames;
425 }
426
427 /**
428 * @return {@link MavenResourcesExecution}
429 */
430 public MavenResourcesExecution copyOf()
431 {
432 MavenResourcesExecution mre = new MavenResourcesExecution();
433 mre.setAdditionalProperties( this.getAdditionalProperties() );
434 mre.setEncoding( this.getEncoding() );
435 mre.setEscapedBackslashesInFilePath( this.isEscapedBackslashesInFilePath() );
436 mre.setEscapeString( this.getEscapeString() );
437 mre.setFileFilters( copyList( this.getFileFilters() ) );
438 mre.setFilterWrappers( copyList( this.getFilterWrappers() ) );
439 mre.setIncludeEmptyDirs( this.isIncludeEmptyDirs() );
440 mre.setInjectProjectBuildFilters( this.isInjectProjectBuildFilters() );
441 mre.setMavenProject( this.getMavenProject() );
442 mre.setMavenSession( this.getMavenSession() );
443 mre.setNonFilteredFileExtensions( copyList( this.getNonFilteredFileExtensions() ) );
444 mre.setOutputDirectory( this.getOutputDirectory() );
445 mre.setOverwrite( this.isOverwrite() );
446 mre.setProjectStartExpressions( copyList( this.getProjectStartExpressions() ) );
447 mre.setResources( copyList( this.getResources() ) );
448 mre.setResourcesBaseDirectory( this.getResourcesBaseDirectory() );
449 mre.setUseDefaultFilterWrappers( this.isUseDefaultFilterWrappers() );
450 mre.setAddDefaultExcludes( this.isAddDefaultExcludes() );
451 mre.setSupportMultiLineFiltering( this.isSupportMultiLineFiltering() );
452 return mre;
453 }
454
455 private <T> List<T> copyList( List<T> lst )
456 {
457 if ( lst == null )
458 {
459 return null;
460 }
461 else if ( lst.isEmpty() )
462 {
463 return new ArrayList<>();
464 }
465 else
466 {
467 return new ArrayList<>( lst );
468 }
469 }
470
471 @Override
472 public boolean isSupportMultiLineFiltering()
473 {
474 return supportMultiLineFiltering;
475 }
476
477 @Override
478 public void setSupportMultiLineFiltering( boolean supportMultiLineFiltering )
479 {
480 this.supportMultiLineFiltering = supportMultiLineFiltering;
481 }
482 }