Coverage Report - org.jbehave.core.io.StoryFinder
 
Classes in this File Line Coverage Branch Coverage Complexity
StoryFinder
100%
39/39
100%
8/8
1.471
StoryFinder$1
100%
3/3
N/A
1.471
StoryFinder$2
100%
3/3
N/A
1.471
StoryFinder$3
100%
5/5
100%
2/2
1.471
 
 1  
 package org.jbehave.core.io;
 2  
 
 3  
 import static java.util.Arrays.asList;
 4  
 
 5  
 import java.io.File;
 6  
 import java.util.ArrayList;
 7  
 import java.util.Collections;
 8  
 import java.util.Comparator;
 9  
 import java.util.List;
 10  
 
 11  
 import org.apache.commons.collections.CollectionUtils;
 12  
 import org.apache.commons.collections.Transformer;
 13  
 import org.apache.commons.lang.StringUtils;
 14  
 import org.codehaus.plexus.util.DirectoryScanner;
 15  
 
 16  
 /**
 17  
  * Finds stories by scanning file system. Stories can be either in the form of
 18  
  * embeddable class names or story paths.
 19  
  */
 20  
 public class StoryFinder {
 21  
 
 22  
     private static final String JAVA = ".java";
 23  
     private final DirectoryScanner scanner;
 24  
     private final String classNameExtension;
 25  
     private final Comparator<? super String> sortingComparator;
 26  
 
 27  
     public StoryFinder() {
 28  10
         this(JAVA);
 29  10
     }
 30  
 
 31  
     public StoryFinder(String classNameExtension) {
 32  11
         this(new DirectoryScanner(), classNameExtension, null);
 33  11
     }
 34  
 
 35  
     public StoryFinder(Comparator<? super String> sortingComparator) {
 36  1
         this(new DirectoryScanner(), JAVA, sortingComparator);
 37  1
     }
 38  
 
 39  12
     public StoryFinder(DirectoryScanner scanner, String classNameExtension, Comparator<? super String> sortingComparator) {
 40  12
         this.scanner = scanner;
 41  12
         this.classNameExtension = classNameExtension;
 42  12
         this.sortingComparator = sortingComparator;
 43  12
     }
 44  
 
 45  
     /**
 46  
      * Finds java source paths from a base directory, allowing for
 47  
      * includes/excludes, and converts them to class names.
 48  
      * 
 49  
      * @param searchInDirectory
 50  
      *            the base directory path to search in
 51  
      * @param includes
 52  
      *            the List of include patterns, or <code>null</code> if none
 53  
      * @param excludes
 54  
      *            the List of exclude patterns, or <code>null</code> if none
 55  
      * @return A List of class names found
 56  
      */
 57  
     public List<String> findClassNames(String searchInDirectory, List<String> includes, List<String> excludes) {
 58  4
         return classNames(normalise(sort(scan(searchInDirectory, includes, excludes))));
 59  
     }
 60  
 
 61  
     /**
 62  
      * Finds paths from a base directory, allowing for includes/excludes. Paths
 63  
      * found are normalised by {@link StoryFinder#normalise(List<String>)}.
 64  
      * 
 65  
      * @param searchInDirectory
 66  
      *            the base directory path to search in
 67  
      * @param includes
 68  
      *            the List of include patterns, or <code>null</code> if none
 69  
      * @param excludes
 70  
      *            the List of exclude patterns, or <code>null</code> if none
 71  
      * @return A List of paths found
 72  
      */
 73  
     public List<String> findPaths(String searchInDirectory, List<String> includes, List<String> excludes) {
 74  3
         return normalise(sort(scan(searchInDirectory, includes, excludes)));
 75  
     }
 76  
 
 77  
     /**
 78  
      * Finds paths from a base directory, allowing for includes/excludes. Paths
 79  
      * found are prefixed with specified path by {@link
 80  
      * StoryFinder#prefix(String, List<String>)} and normalised by {@link
 81  
      * StoryFinder#normalise(List<String>)}.
 82  
      * 
 83  
      * @param searchInDirectory
 84  
      *            the base directory path to search in
 85  
      * @param includes
 86  
      *            the List of include patterns, or <code>null</code> if none
 87  
      * @param excludes
 88  
      *            the List of exclude patterns, or <code>null</code> if none
 89  
      * @param prefixWith
 90  
      *            the root path prefixed to all paths found, or
 91  
      *            <code>null</code> if none
 92  
      * @return A List of paths found
 93  
      */
 94  
     public List<String> findPaths(String searchInDirectory, List<String> includes, List<String> excludes,
 95  
             String prefixWith) {
 96  2
         return normalise(prefix(prefixWith, sort(scan(searchInDirectory, includes, excludes))));
 97  
     }
 98  
 
 99  
     protected List<String> normalise(List<String> paths) {
 100  11
         List<String> transformed = new ArrayList<String>(paths);
 101  11
         CollectionUtils.transform(transformed, new Transformer() {
 102  
             public Object transform(Object input) {
 103  85
                 String path = (String) input;
 104  85
                 return path.replace('\\', '/');
 105  
             }
 106  
         });
 107  11
         return transformed;
 108  
     }
 109  
 
 110  
     protected List<String> prefix(final String prefixWith, List<String> paths) {
 111  2
         if (StringUtils.isBlank(prefixWith)) {
 112  1
             return paths;
 113  
         }
 114  1
         List<String> transformed = new ArrayList<String>(paths);
 115  1
         CollectionUtils.transform(transformed, new Transformer() {
 116  
             public Object transform(Object input) {
 117  4
                 String path = (String) input;
 118  4
                 return prefixWith + path;
 119  
             }
 120  
         });
 121  1
         return transformed;
 122  
     }
 123  
 
 124  
     protected List<String> classNames(List<String> paths) {
 125  4
         List<String> trasformed = new ArrayList<String>(paths);
 126  4
         CollectionUtils.transform(trasformed, new Transformer() {
 127  
             public Object transform(Object input) {
 128  8
                 String path = (String) input;
 129  8
                 if (!StringUtils.endsWithIgnoreCase(path, classNameExtension())) {
 130  1
                     return input;
 131  
                 }
 132  7
                 return StringUtils.removeEndIgnoreCase(path, classNameExtension()).replace('/', '.');
 133  
             }
 134  
         });
 135  4
         return trasformed;
 136  
     }
 137  
 
 138  
     protected String classNameExtension() {
 139  15
         return classNameExtension;
 140  
     }
 141  
 
 142  
     protected List<String> sort(List<String> input) {
 143  9
         List<String> sorted = new ArrayList<String>(input);
 144  9
         Collections.sort(sorted, sortingComparator());
 145  9
         return sorted;
 146  
     }
 147  
 
 148  
     /**
 149  
      * Comparator used for sorting.  A <code>null</code> comparator means
 150  
      * that {@link Collections#sort()} will use natural ordering.
 151  
      * 
 152  
      * @return A Comparator or <code>null</code> for natural ordering.
 153  
      */
 154  
     protected Comparator<? super String> sortingComparator() {
 155  9
         return sortingComparator;
 156  
     }
 157  
 
 158  
     protected List<String> scan(String basedir, List<String> includes, List<String> excludes) {
 159  9
         if (!new File(basedir).exists()) {
 160  1
             return new ArrayList<String>();
 161  
         }
 162  8
         scanner.setBasedir(basedir);
 163  8
         if (includes != null) {
 164  7
             scanner.setIncludes(includes.toArray(new String[includes.size()]));
 165  
         }
 166  8
         if (excludes != null) {
 167  7
             scanner.setExcludes(excludes.toArray(new String[excludes.size()]));
 168  
         }
 169  8
         scanner.scan();
 170  8
         return asList(scanner.getIncludedFiles());
 171  
     }
 172  
 
 173  
 }