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