View Javadoc
1   package com.soebes.maven.plugins.iterator;
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.util.ArrayList;
24  import java.util.Collections;
25  import java.util.Comparator;
26  import java.util.List;
27  
28  import org.apache.commons.io.comparator.NameFileComparator;
29  import org.apache.commons.io.filefilter.DirectoryFileFilter;
30  import org.apache.commons.io.filefilter.FileFilterUtils;
31  import org.apache.commons.io.filefilter.HiddenFileFilter;
32  import org.apache.commons.io.filefilter.IOFileFilter;
33  import org.apache.maven.execution.MavenSession;
34  import org.apache.maven.plugin.AbstractMojo;
35  import org.apache.maven.plugin.MojoExecutionException;
36  import org.apache.maven.plugins.annotations.Parameter;
37  import org.apache.maven.project.MavenProject;
38  
39  /**
40   * @author Karl-Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a>
41   */
42  public abstract class AbstractIteratorMojo
43      extends AbstractMojo
44  {
45      /**
46       * The project currently being build.
47       */
48      @Parameter( required = true, readonly = true, defaultValue = "${project}" )
49      private MavenProject mavenProject;
50  
51      /**
52       * The current Maven session.
53       */
54      @Parameter( required = true, readonly = true, defaultValue = "${session}" )
55      private MavenSession mavenSession;
56  
57      /**
58       * If you like to skip the execution.
59       */
60      @Parameter( property = "iterator.skip", defaultValue = "false" )
61      private boolean skip;
62  
63      /**
64       * Fail the execution at the end of all iterations or fail the whole if one iteration step fails.
65       */
66      @Parameter( property = "iterator.failAtEnd", defaultValue = "false" )
67      private boolean failAtEnd;
68  
69      /**
70       * The token the iterator placeholder begins with.
71       */
72      @Parameter( required = true, defaultValue = "@" )
73      private String beginToken;
74  
75      /**
76       * The token the iterator placeholder ends with.
77       */
78      @Parameter( required = true, defaultValue = "@" )
79      private String endToken;
80  
81      /**
82       * The name of the iterator variable.
83       */
84      @Parameter( required = true, defaultValue = "item" )
85      private String iteratorName;
86  
87      /**
88       * Here you can define the items which will be iterated through.
89       * 
90       * <pre>
91       * {@code 
92       *   <items>
93       *     <item>one</item>
94       *     <item>two</item>
95       *     <item>three</item>
96       *     ..
97       *   </items>}
98       * </pre>
99       */
100     @Parameter( property = "iterator.items" )
101     private List<String> items;
102 
103     /**
104      * If you like to have items to iterate through which also contain supplemental properties. This can be done by
105      * using the following:
106      * 
107      * <pre>
108      * {@code 
109      *   <itemsWithProperties>
110      *     <itemWithProperty>
111      *       <name>one</name>
112      *       <properties>
113      *         <xyz>google</xyz>
114      *       </properties>
115      *     </itemWithProperty>
116      *     <itemWithProperty>
117      *       <name>two</name>
118      *       <properties>
119      *         <xyz>theseverside</xyz>
120      *       </properties>
121      *     </itemWithProperty>
122      *     ..
123      *   </items>}
124      * </pre>
125      * 
126      * You are not determined having the same properties for the iterations. You can use different properties for each
127      * iteration.
128      */
129     @Parameter
130     private List<ItemWithProperties> itemsWithProperties;
131 
132     /**
133      * The list of items which will be iterated through. {@code <content>one, two, three</content>}
134      */
135     @Parameter
136     private String content;
137 
138     /**
139      * The delimiter which will be used to split the {@link #content}.
140      */
141     @Parameter( defaultValue = "," )
142     private String delimiter;
143 
144     /**
145      * By using this folder you define a folder which sub folders will be used to iterate over. It will be iterated over
146      * the directories but not the sub folders so no recursion will be done. The order of the iterated elements is done
147      * by {@link #sortOrder}.
148      */
149     @Parameter
150     private File folder;
151 
152     /**
153      * This defines the sort order for the folders which will be iterated over.
154      * {@link NameFileComparator#NAME_COMPARATOR} {@link NameFileComparator#NAME_INSENSITIVE_COMPARATOR}
155      * {@link NameFileComparator#NAME_INSENSITIVE_REVERSE} {@link NameFileComparator#NAME_REVERSE}
156      * {@link NameFileComparator#NAME_SYSTEM_COMPARATOR} {@link NameFileComparator#NAME_SYSTEM_REVERSE}
157      */
158     @Parameter( defaultValue = "NAME_COMPARATOR" )
159     private String sortOrder;
160 
161     public boolean isSortOrderValid( String sortOrder )
162     {
163         boolean result = sortOrder.equalsIgnoreCase( "NAME_COMPARATOR" )
164             || sortOrder.equalsIgnoreCase( "NAME_INSENSITIVE_COMPARATOR" )
165             || sortOrder.equalsIgnoreCase( "NAME_INSENSITIVE_REVERSE" ) || sortOrder.equalsIgnoreCase( "NAME_REVERSE" )
166             || sortOrder.equalsIgnoreCase( "NAME_SYSTEM_COMPARATOR" )
167             || sortOrder.equalsIgnoreCase( "NAME_SYSTEM_REVERSE" );
168         return result;
169     }
170 
171     protected Comparator<File> convertSortOrder()
172     {
173         Comparator<File> result = NameFileComparator.NAME_COMPARATOR;
174         if ( getSortOrder().equalsIgnoreCase( "NAME_INSENSITIVE_COMPARATOR" ) )
175         {
176             result = NameFileComparator.NAME_INSENSITIVE_COMPARATOR;
177         }
178         else if ( getSortOrder().equalsIgnoreCase( "NAME_INSENSITIVE_REVERSE" ) )
179         {
180             result = NameFileComparator.NAME_INSENSITIVE_REVERSE;
181         }
182         else if ( getSortOrder().equalsIgnoreCase( "NAME_REVERSE" ) )
183         {
184             result = NameFileComparator.NAME_REVERSE;
185         }
186         else if ( getSortOrder().equalsIgnoreCase( "NAME_SYSTEM_COMPARATOR" ) )
187         {
188             result = NameFileComparator.NAME_SYSTEM_COMPARATOR;
189         }
190         else if ( getSortOrder().equalsIgnoreCase( "NAME_SYSTEM_REVERSE" ) )
191         {
192             result = NameFileComparator.NAME_SYSTEM_REVERSE;
193         }
194         return result;
195     }
196 
197     public List<String> getFolders()
198         throws MojoExecutionException
199     {
200         IOFileFilter folders = FileFilterUtils.and( HiddenFileFilter.VISIBLE, DirectoryFileFilter.DIRECTORY );
201         IOFileFilter makeSVNAware = FileFilterUtils.makeSVNAware( folders );
202         IOFileFilter makeCVSAware = FileFilterUtils.makeCVSAware( makeSVNAware );
203 
204         String[] list = folder.list( makeCVSAware );
205         if ( list == null )
206         {
207             throw new MojoExecutionException( "The specified folder doesn't exist: " + folder );
208         }
209 
210         List<File> listOfDirectories = new ArrayList<File>();
211         for ( String item : list )
212         {
213             listOfDirectories.add( new File( folder, item ) );
214         }
215 
216         Collections.sort( listOfDirectories, convertSortOrder() );
217         List<String> resultList = new ArrayList<String>();
218         for ( File file : listOfDirectories )
219         {
220             resultList.add( file.getName() );
221         }
222         return resultList;
223     }
224 
225     private List<String> getContentAsList()
226     {
227         List<String> result = new ArrayList<String>();
228         String[] resultArray = content.split( delimiter );
229         for ( String item : resultArray )
230         {
231             result.add( item.trim() );
232         }
233         return result;
234     }
235 
236     /**
237      * Convert all types {@code content}, {@code items} or {@code ItemsWithProperties} into the same type.
238      * 
239      * @return list {@link ItemWithProperties}
240      * @throws MojoExecutionException In case of an error.
241      */
242     protected List<ItemWithProperties> getItemsConverted()
243         throws MojoExecutionException
244     {
245         List<ItemWithProperties> result = new ArrayList<>();
246 
247         if ( isItemsWithPropertiesSet() )
248         {
249             result = getItemsWithProperties();
250         }
251         else if ( isContentSet() )
252         {
253             for ( String itemName : getContentAsList() )
254             {
255                 result.add( new ItemWithProperties( itemName, ItemWithProperties.NO_PROPERTIES ) );
256             }
257         }
258         else if ( isItemsSet() )
259         {
260             for ( String itemName : getItems() )
261             {
262                 result.add( new ItemWithProperties( itemName, ItemWithProperties.NO_PROPERTIES ) );
263             }
264         }
265         else if ( isFolderSet() )
266         {
267             for ( String itemName : getFolders() )
268             {
269                 result.add( new ItemWithProperties( itemName, ItemWithProperties.NO_PROPERTIES ) );
270             }
271         }
272 
273         return result;
274     }
275 
276     /**
277      * This is just a convenience method to get the combination of {@link #getBeginToken()}, {@link #getIteratorName()}
278      * and {@link #getEndToken()}.
279      * 
280      * @return The combined string.
281      */
282     protected String getPlaceHolder()
283     {
284         return getBeginToken() + getIteratorName() + getEndToken();
285     }
286 
287     protected boolean isItemsNull()
288     {
289         return items == null;
290     }
291 
292     protected boolean isItemsWithPropertiesNull()
293     {
294         return itemsWithProperties == null;
295     }
296 
297     protected boolean isItemsWithPropertiesSet()
298     {
299         return !isItemsWithPropertiesNull() && !itemsWithProperties.isEmpty();
300     }
301 
302     protected boolean isItemsSet()
303     {
304         return !isItemsNull() && !items.isEmpty();
305     }
306 
307     protected boolean isContentNull()
308     {
309         return content == null;
310     }
311 
312     protected boolean isContentSet()
313     {
314         // @TODO: Check if content.trim() couldn't be done more efficient?
315         return content != null && content.trim().length() > 0;
316     }
317 
318     protected boolean isFolderSet()
319     {
320         return this.folder != null;
321     }
322 
323     protected boolean isFolderNull()
324     {
325         return this.folder == null;
326     }
327 
328     public File getFolder()
329     {
330         return this.folder;
331     }
332 
333     public void setFolder( File folder )
334     {
335         this.folder = folder;
336     }
337 
338     protected boolean isMoreThanOneSet()
339     {
340         // a ^ b ^ c && ! (a && b && c)
341         boolean result = isItemsSet() ^ isContentSet() ^ isItemsWithPropertiesSet() ^ isFolderSet()
342             && !( isItemsSet() && isContentSet() && isItemsWithPropertiesSet() && isFolderSet() );
343         return !result;
344     }
345 
346     protected boolean isNoneSet()
347     {
348         return isItemsNull() && isContentNull() && isItemsWithPropertiesNull() && isFolderNull();
349     }
350 
351     public void setSortOrder( String sortOrder )
352     {
353         this.sortOrder = sortOrder;
354     }
355 
356     public String getSortOrder()
357     {
358         return sortOrder;
359     }
360 
361     public String getContent()
362     {
363         return content;
364     }
365 
366     public void setContent( String content )
367     {
368         this.content = content;
369     }
370 
371     public String getDelimiter()
372     {
373         return delimiter;
374     }
375 
376     public void setDelimiter( String delimiter )
377     {
378         this.delimiter = delimiter;
379     }
380 
381     public String getBeginToken()
382     {
383         return beginToken;
384     }
385 
386     public void setBeginToken( String beginToken )
387     {
388         this.beginToken = beginToken;
389     }
390 
391     public String getEndToken()
392     {
393         return endToken;
394     }
395 
396     public void setEndToken( String endToken )
397     {
398         this.endToken = endToken;
399     }
400 
401     public String getIteratorName()
402     {
403         return iteratorName;
404     }
405 
406     public void setIteratorName( String iteratorName )
407     {
408         this.iteratorName = iteratorName;
409     }
410 
411     public void setItems( List<String> items )
412     {
413         this.items = items;
414     }
415 
416     public List<String> getItems()
417     {
418         return items;
419     }
420 
421     public boolean isSkip()
422     {
423         return skip;
424     }
425 
426     public boolean isFailAtEnd()
427     {
428         return failAtEnd;
429     }
430 
431     public List<ItemWithProperties> getItemsWithProperties()
432     {
433         return itemsWithProperties;
434     }
435 
436     public void setItemsWithProperties( List<ItemWithProperties> itemsWithProperties )
437     {
438         this.itemsWithProperties = itemsWithProperties;
439     }
440 
441     public MavenProject getMavenProject()
442     {
443         return mavenProject;
444     }
445 
446     public void setMavenProject( MavenProject mavenProject )
447     {
448         this.mavenProject = mavenProject;
449     }
450 
451     public MavenSession getMavenSession()
452     {
453         return mavenSession;
454     }
455 
456     public void setMavenSession( MavenSession mavenSession )
457     {
458         this.mavenSession = mavenSession;
459     }
460 
461 }