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