Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 274   Methods: 7
NCLOC: 131   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ZipScanner.java 76.7% 85.5% 100% 83.8%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 
 55   
 package org.apache.tools.ant.types;
 56   
 
 57   
 import java.io.File;
 58   
 import java.io.FileInputStream;
 59   
 import java.io.IOException;
 60   
 import java.util.Vector;
 61   
 import java.util.Hashtable;
 62   
 import java.util.Enumeration;
 63   
 import java.util.zip.ZipInputStream;
 64   
 import java.util.zip.ZipEntry;
 65   
 import java.util.zip.ZipException;
 66   
 
 67   
 import org.apache.tools.ant.BuildException;
 68   
 import org.apache.tools.ant.DirectoryScanner;
 69   
 import org.apache.tools.ant.Project;
 70   
 
 71   
 /**
 72   
  * ZipScanner accesses the pattern matching algorithm in DirectoryScanner,
 73   
  * which are protected methods that can only be accessed by subclassing.
 74   
  *
 75   
  * This implementation of FileScanner defines getIncludedFiles to return
 76   
  * the matching Zip entries.
 77   
  *
 78   
  * @author Don Ferguson <a href="mailto:don@bea.com">don@bea.com</a>
 79   
  * @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a>
 80   
  */
 81   
 public class ZipScanner extends DirectoryScanner {
 82   
 
 83   
     /**
 84   
      * The zip file which should be scanned.
 85   
      */
 86   
     protected File srcFile;
 87   
     /**
 88   
      * to record the last scanned zip file with its modification date
 89   
      */
 90   
     private Resource lastScannedResource;
 91   
     /**
 92   
      * record list of all zip entries
 93   
      */
 94   
     private Hashtable myentries;
 95   
 
 96   
     /**
 97   
      * Sets the srcFile for scanning. This is the jar or zip file that
 98   
      * is scanned for matching entries.
 99   
      *
 100   
      * @param srcFile the (non-null) zip file name for scanning
 101   
      */
 102  34
     public void setSrc(File srcFile) {
 103  34
         this.srcFile = srcFile;
 104   
     }
 105   
 
 106   
     /**
 107   
      * Returns the names of the files which matched at least one of the
 108   
      * include patterns and none of the exclude patterns.
 109   
      * The names are relative to the base directory.
 110   
      *
 111   
      * @return the names of the files which matched at least one of the
 112   
      *         include patterns and none of the exclude patterns.
 113   
      */
 114  16
     public String[] getIncludedFiles() {
 115  16
         if (srcFile != null) {
 116  16
             Vector myvector = new Vector();
 117   
             // first check if the archive needs to be scanned again
 118  16
             scanme();
 119  16
             for (Enumeration e = myentries.elements(); e.hasMoreElements() ;) {
 120  331
                 Resource myresource= (Resource) e.nextElement();
 121  331
                 if (!myresource.isDirectory() && match(myresource.getName())) {
 122  245
                     myvector.addElement(myresource.getName());
 123   
                 }
 124   
             }
 125  16
             String[] files = new String[myvector.size()];
 126  16
             myvector.copyInto(files);
 127  16
             return files;
 128   
         } else {
 129  0
             return super.getIncludedFiles();
 130   
         }
 131   
     }
 132   
 
 133   
     /**
 134   
      * Returns the names of the directories which matched at least one of the
 135   
      * include patterns and none of the exclude patterns.
 136   
      * The names are relative to the base directory.
 137   
      *
 138   
      * @return the names of the directories which matched at least one of the
 139   
      * include patterns and none of the exclude patterns.
 140   
      */
 141  9
     public String[] getIncludedDirectories() {
 142  9
         if (srcFile != null) {
 143  9
             Vector myvector=new Vector();
 144   
             // first check if the archive needs to be scanned again
 145  9
             scanme();
 146  9
             for (Enumeration e = myentries.elements(); e.hasMoreElements() ;) {
 147  312
                 Resource myresource= (Resource) e.nextElement();
 148  312
                 if (myresource.isDirectory() && match(myresource.getName())) {
 149  67
                     myvector.addElement(myresource.getName());
 150   
                 }
 151   
             }
 152  9
             String[] files = new String[myvector.size()];
 153  9
             myvector.copyInto(files);
 154  9
             return files;
 155   
         } else {
 156  0
             return super.getIncludedDirectories();
 157   
         }
 158   
     }
 159   
 
 160   
     /**
 161   
      * Initialize DirectoryScanner data structures.
 162   
      */
 163  16
     public void init() {
 164  16
         if (includes == null) {
 165   
             // No includes supplied, so set it to 'matches all'
 166  14
             includes = new String[1];
 167  14
             includes[0] = "**";
 168   
         }
 169  16
         if (excludes == null) {
 170  0
             excludes = new String[0];
 171   
         }
 172   
     }
 173   
 
 174   
     /**
 175   
      * Matches a jar entry against the includes/excludes list,
 176   
      * normalizing the path separator.
 177   
      *
 178   
      * @param path the (non-null) path name to test for inclusion
 179   
      *
 180   
      * @return <code>true</code> if the path should be included
 181   
      *         <code>false</code> otherwise.
 182   
      */
 183  325
     public boolean match(String path) {
 184  325
         String vpath = path.replace('/', File.separatorChar).
 185   
             replace('\\', File.separatorChar);
 186  325
         return isIncluded(vpath) && !isExcluded(vpath);
 187   
     }
 188   
 
 189   
     /**
 190   
      * @param name path name of the file sought in the archive
 191   
      *
 192   
      * @since Ant 1.5.2
 193   
      */
 194  433
     public Resource getResource(String name) {
 195  433
         if (srcFile == null) {
 196  0
             return super.getResource(name);
 197  433
         } else if (name.equals("")) {
 198   
             // special case in ZIPs, we do not want this thing included
 199  0
             return new Resource("", true, Long.MAX_VALUE, true);
 200   
         }
 201   
 
 202   
         // first check if the archive needs to be scanned again
 203  433
         scanme();
 204  433
         if (myentries.containsKey(name)) {
 205  330
             return (Resource) myentries.get(name);
 206  103
         } else if (myentries.containsKey(name + "/")) {
 207  0
             return (Resource) myentries.get(name + "/");
 208   
         } else {
 209  103
             return new Resource(name);
 210   
         }
 211   
     }
 212   
 
 213   
     /**
 214   
      * if the datetime of the archive did not change since
 215   
      * lastScannedResource was initialized returns immediately else if
 216   
      * the archive has not been scanned yet, then all the zip entries
 217   
      * are put into the vector myentries as a vector of the resource
 218   
      * type
 219   
      */
 220  458
     private void scanme() {
 221  458
         Resource thisresource = new Resource(srcFile.getAbsolutePath(),
 222   
                                              srcFile.exists(),
 223   
                                              srcFile.lastModified());
 224   
 
 225   
         // spare scanning again and again
 226  458
         if (lastScannedResource != null
 227   
             && lastScannedResource.getName().equals(thisresource.getName())
 228   
             && lastScannedResource.getLastModified()
 229   
             == thisresource.getLastModified()) {
 230  424
             return;
 231   
         }
 232   
 
 233  34
         ZipEntry entry = null;
 234  34
         ZipInputStream in = null;
 235  34
         myentries = new Hashtable();
 236  34
         try {
 237  34
             try {
 238  34
                 in = new ZipInputStream(new FileInputStream(srcFile));
 239   
             } catch (IOException ex) {
 240  0
                 throw new BuildException("problem opening " + srcFile, ex);
 241   
             }
 242   
 
 243  34
             while (true) {
 244  415
                 try {
 245  415
                     entry = in.getNextEntry();
 246  415
                     if (entry == null) {
 247  34
                         break;
 248   
                     }
 249  381
                     myentries.put(new String(entry.getName()),
 250   
                                   new Resource(entry.getName(), true,
 251   
                                                entry.getTime(), 
 252   
                                                entry.isDirectory()));
 253   
                 } catch (ZipException ex) {
 254  0
                     throw new BuildException("problem reading " + srcFile,
 255   
                                              ex);
 256   
                 } catch (IOException e) {
 257  0
                     throw new BuildException("problem reading zip entry from " 
 258   
                                              + srcFile, e);
 259   
                 }
 260   
             }
 261   
         } finally {
 262  34
             if (in != null) {
 263  34
                 try {
 264  34
                     in.close();
 265   
                 } catch (IOException ex) {
 266   
                     // swallow
 267   
                 }
 268   
             }
 269   
         }
 270   
         // record data about the last scanned resource
 271  34
         lastScannedResource = thisresource;
 272   
     }
 273   
 }
 274