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