Coverage Report - org.jbehave.core.io.JarFileScanner
 
Classes in this File Line Coverage Branch Coverage Complexity
JarFileScanner
95%
41/43
100%
24/24
3
JarFileScanner$1
100%
3/3
100%
2/2
3
 
 1  
 package org.jbehave.core.io;
 2  
 
 3  
 import java.io.File;
 4  
 import java.io.IOException;
 5  
 import java.net.URL;
 6  
 import java.util.ArrayList;
 7  
 import java.util.Arrays;
 8  
 import java.util.Enumeration;
 9  
 import java.util.List;
 10  
 import java.util.jar.JarEntry;
 11  
 import java.util.jar.JarFile;
 12  
 
 13  
 import org.apache.commons.collections.CollectionUtils;
 14  
 import org.apache.commons.collections.Transformer;
 15  
 import org.codehaus.plexus.util.SelectorUtils;
 16  
 
 17  
 import static java.util.Arrays.asList;
 18  
 import static org.apache.commons.lang.StringUtils.isBlank;
 19  
 
 20  
 /**
 21  
  * Find all matching file entries in a jar.
 22  
  */
 23  
 public class JarFileScanner {
 24  
 
 25  
     private URL jarURL;
 26  
     private List<String> includes;
 27  
     private List<String> excludes;
 28  
 
 29  
     public JarFileScanner(String jarPath, String includes, String excludes) {
 30  6
         this(jarPath, asList(includes), asList(excludes));
 31  6
     }
 32  
 
 33  
     public JarFileScanner(String jarPath, List<String> includes, List<String> excludes) {
 34  9
         this(CodeLocations.codeLocationFromPath(jarPath), includes, excludes);
 35  9
     }
 36  
 
 37  
     public JarFileScanner(URL jarURL, String includes, String excludes) {
 38  0
         this(jarURL, asList(includes), asList(excludes));
 39  0
     }
 40  
 
 41  9
     public JarFileScanner(URL jarURL, List<String> includes, List<String> excludes) {
 42  9
         this.jarURL = jarURL;
 43  9
         this.includes = ( includes != null ? toLocalPath(includes) : Arrays.<String>asList() );
 44  9
         this.excludes = ( excludes != null ? toLocalPath(excludes) : Arrays.<String>asList() );
 45  9
     }
 46  
 
 47  
     /**
 48  
      * Scans the jar file and returns the paths that match the includes and excludes.
 49  
      * 
 50  
      * @return A List of paths
 51  
      * @throws An IllegalStateException when an I/O error occurs in reading the jar file.
 52  
      */
 53  
     public List<String> scan() {
 54  
         try {
 55  9
             JarFile jar = new JarFile(jarURL.getFile());
 56  
             try {
 57  8
                 List<String> result = new ArrayList<String>();
 58  8
                 Enumeration<JarEntry> en = jar.entries();
 59  40
                 while (en.hasMoreElements()) {
 60  32
                     JarEntry entry = en.nextElement();
 61  32
                     String path = entry.getName();
 62  32
                     boolean match = includes.size() == 0;
 63  32
                     if (!match) {
 64  28
                         for (String pattern : includes) {
 65  28
                             if ( patternMatches(pattern, path)) {
 66  15
                                 match = true;
 67  15
                                 break;
 68  
                             }
 69  13
                         }
 70  
                     }
 71  32
                     if (match) {
 72  19
                         for (String pattern : excludes) {
 73  15
                             if ( patternMatches(pattern, path)) {
 74  3
                                 match = false;
 75  3
                                 break;
 76  
                             }
 77  12
                         }
 78  
                     }
 79  32
                     if (match) {
 80  16
                         result.add(path);
 81  
                     }
 82  32
                 }
 83  8
                 return result;
 84  
             } finally {
 85  8
                 jar.close();
 86  
             }
 87  1
         } catch (IOException e) {
 88  1
             throw new IllegalStateException(e);
 89  
         }
 90  
     }
 91  
 
 92  
     private List<String> toLocalPath(List<String> patternList) {
 93  16
         List<String> transformed = new ArrayList<String>(patternList);
 94  16
         CollectionUtils.transform(transformed, new Transformer() {
 95  
             public Object transform(Object input) {
 96  16
                 String pattern=(String)input;
 97  16
                 return pattern!=null ? pattern.replace('/', File.separatorChar) : null;
 98  
             }
 99  
         });
 100  16
         return transformed;
 101  
     }
 102  
 
 103  
     private boolean patternMatches(String pattern, String path) {
 104  43
         if ( isBlank(pattern) ) return false;
 105  
         // SelectorUtils assumes local path separator for path and pattern
 106  29
         String localPath = path.replace('/', File.separatorChar);
 107  29
         return SelectorUtils.matchPath(pattern, localPath);
 108  
     }
 109  
 
 110  
 }