bodewig     2003/01/22 04:36:41

  Modified:    .        WHATSNEW
               src/main/org/apache/tools/ant DirectoryScanner.java
               src/main/org/apache/tools/ant/taskdefs Jar.java Zip.java
               src/main/org/apache/tools/ant/types ZipScanner.java
               src/main/org/apache/tools/ant/util SourceFileScanner.java
               src/main/org/apache/tools/zip ZipOutputStream.java
               src/testcases/org/apache/tools/ant/taskdefs JarTest.java
  Added:       src/main/org/apache/tools/ant ResourceScanner.java
               src/main/org/apache/tools/ant/types Resource.java
                        ResourceFactory.java
               src/main/org/apache/tools/ant/util SourceSelector.java
  Log:
  Initial fix for the <jar> doesn't update bug, will need some
  refinement (see extra mail to list).
  
  PR: 10755
  Submitted by: Antoine Levy-Lambert <levylambert at tiscali-dsl dot de>
  
  Revision  Changes    Path
  1.345     +3 -0      jakarta-ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/WHATSNEW,v
  retrieving revision 1.344
  retrieving revision 1.345
  diff -u -r1.344 -r1.345
  --- WHATSNEW  19 Jan 2003 01:32:10 -0000      1.344
  +++ WHATSNEW  22 Jan 2003 12:36:40 -0000      1.345
  @@ -19,6 +19,9 @@
   
   * <xmlproperty> will no longer fail if the file to be loaded doesn't exist.
   
  +* ZipScanner#getIncludedFiles will now return the names of the ZipEntries
  +  that have been matched instead of the name of the archive.
  +
   Fixed bugs:
   -----------
   * <translate> was not ignoring comment lines.
  
  
  
  1.34      +83 -1     
jakarta-ant/src/main/org/apache/tools/ant/DirectoryScanner.java
  
  Index: DirectoryScanner.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/DirectoryScanner.java,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- DirectoryScanner.java     20 Jan 2003 08:09:01 -0000      1.33
  +++ DirectoryScanner.java     22 Jan 2003 12:36:41 -0000      1.34
  @@ -57,6 +57,7 @@
   import java.io.File;
   import java.io.IOException;
   import java.util.Vector;
  +import org.apache.tools.ant.types.Resource;
   import org.apache.tools.ant.types.selectors.FileSelector;
   import org.apache.tools.ant.types.selectors.SelectorScanner;
   import org.apache.tools.ant.types.selectors.SelectorUtils;
  @@ -149,7 +150,7 @@
    * @author Magesh Umasankar
    * @author <a href="mailto:[EMAIL PROTECTED]">Bruce Atherton</a>
    */
  -public class DirectoryScanner implements FileScanner, SelectorScanner {
  +public class DirectoryScanner implements ResourceScanner, SelectorScanner {
   
       /**
        * Patterns which should be excluded by default.
  @@ -201,6 +202,11 @@
        */
       protected Vector filesIncluded;
   
  +    /**
  +     * the same as filesIncluded, but in terms of Resource
  +     */
  +    private Vector filesIncludedR;
  +
       /** The files which did not match any includes or selectors. */
       protected Vector filesNotIncluded;
   
  @@ -214,6 +220,10 @@
        *  and were selected.
        */
       protected Vector dirsIncluded;
  +    /** The directories which matched at least one include and no excludes
  +     *  and were selected, as resources
  +     */
  +    private Vector dirsIncludedR;
   
       /** The directories which were found and did not match any includes. */
       protected Vector dirsNotIncluded;
  @@ -545,10 +555,12 @@
           }
   
           filesIncluded    = new Vector();
  +        filesIncludedR   = new Vector();
           filesNotIncluded = new Vector();
           filesExcluded    = new Vector();
           filesDeselected  = new Vector();
           dirsIncluded     = new Vector();
  +        dirsIncludedR    = new Vector();
           dirsNotIncluded  = new Vector();
           dirsExcluded     = new Vector();
           dirsDeselected   = new Vector();
  @@ -557,6 +569,10 @@
               if (!isExcluded("")) {
                   if (isSelected("",basedir)) {
                       dirsIncluded.addElement("");
  +                    dirsIncludedR.addElement(new Resource("", true, 
  +                                                          basedir
  +                                                          .lastModified(),
  +                                                          true));
                   } else {
                       dirsDeselected.addElement("");
                   }
  @@ -675,6 +691,11 @@
                       if (!isExcluded(name)) {
                           if (isSelected(name,file)) {
                               dirsIncluded.addElement(name);
  +                            dirsIncludedR.addElement(new Resource(name,
  +                                                                  true,
  +                                                                  file
  +                                                                  
.lastModified(),
  +                                                                  true));
                               if (fast) {
                                   scandir(file, name + File.separator, fast);
                               }
  @@ -708,6 +729,11 @@
                       if (!isExcluded(name)) {
                           if (isSelected(name,file)) {
                               filesIncluded.addElement(name);
  +                            filesIncludedR.addElement(new Resource(name,
  +                                                                   true,
  +                                                                   file
  +                                                                   
.lastModified(),
  +                                                                   false));
                           } else {
                               everythingIncluded = false;
                               filesDeselected.addElement(name);
  @@ -810,6 +836,26 @@
           }
           return files;
       }
  +    /**
  +     * Returns the resources of the files which matched at least one
  +     * of the include patterns and none of the exclude patterns.  The
  +     * names are relative to the base directory.
  +     *
  +     * @return resource information for the files which matched at
  +     * least one of the include patterns and none of the exclude
  +     * patterns.
  +     *
  +     * @since Ant 1.5.2
  +     */
  +    public Resource[] getIncludedFileResources() {
  +        int count = filesIncludedR.size();
  +        Resource[] resources = new Resource[count];
  +        for (int i = 0; i < count; i++) {
  +            resources[i] = 
  +                (Resource) ((Resource) filesIncludedR.elementAt(i)).clone();
  +        }
  +        return resources;
  +    }
   
       /**
        * Returns the names of the files which matched none of the include
  @@ -891,6 +937,25 @@
       }
   
       /**
  +     * Returns the resource object for the directories which matched
  +     * at least one of the include patterns and none of the exclude
  +     * patterns.  The names are relative to the base directory.
  +     *
  +     * @return the names of the directories which matched at least one of the
  +     * include patterns and none of the exclude patterns.
  +     *
  +     * @since Ant 1.5.2
  +     */
  +     public Resource[] getIncludedDirectoryResources() {
  +         int count = dirsIncludedR.size();
  +         Resource[] directories = new Resource[count];
  +         for (int i = 0; i < count; i++) {
  +             directories[i] = 
  +                 (Resource) ((Resource) dirsIncludedR.elementAt(i)).clone();
  +         }
  +         return directories;
  +     }
  +    /**
        * Returns the names of the directories which matched none of the include
        * patterns. The names are relative to the base directory. This involves
        * performing a slow scan if one has not already been completed.
  @@ -968,4 +1033,21 @@
           }
           excludes = newExcludes;
       }
  +
  +    /**
  +     * @param name path name of the file relative to the dir attribute.
  +     *
  +     * @since Ant 1.5.2
  +     */
  +    public Resource getResource(String name) {
  +        File f = null;
  +        if (basedir != null) {
  +            f = new File(basedir, name);
  +        } else {
  +            f = new File(name);
  +        }            
  +        return new Resource(name, f.exists(), f.lastModified(), 
  +                            f.isDirectory());
  +    }
  +
   }
  
  
  
  1.1                  
jakarta-ant/src/main/org/apache/tools/ant/ResourceScanner.java
  
  Index: ResourceScanner.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.tools.ant;
  
  import org.apache.tools.ant.types.Resource;
  import org.apache.tools.ant.types.ResourceFactory;
  
  /**
   * Extends the FileScanner concept to [EMAIL PROTECTED]
   * org.apache.tools.ant.types.Resource Resources}.
   *
   * @since Ant 1.5.2
   */
  public interface ResourceScanner extends FileScanner, ResourceFactory {
  
      /**
       * Returns resources for the directories which matched at least
       * one of the include patterns and none of the exclude patterns.
       *
       * @return resources for the directories which matched at least
       * one of the include patterns and none of the exclude patterns.
       */
      Resource[] getIncludedDirectoryResources();
      
      /**
       * Returns resources for the files which matched at least one of
       * the include patterns and none of the exclude patterns.
       *
       * @return the names of the files which matched at least one of the
       *         include patterns and none of the exclude patterns.
       */
      Resource[] getIncludedFileResources();
      
  }
  
  
  
  1.60      +6 -3      
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Jar.java
  
  Index: Jar.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Jar.java,v
  retrieving revision 1.59
  retrieving revision 1.60
  diff -u -r1.59 -r1.60
  --- Jar.java  17 Jan 2003 12:30:44 -0000      1.59
  +++ Jar.java  22 Jan 2003 12:36:41 -0000      1.60
  @@ -68,9 +68,10 @@
   import java.util.zip.ZipEntry;
   import java.util.zip.ZipFile;
   import org.apache.tools.ant.BuildException;
  -import org.apache.tools.ant.FileScanner;
   import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.ResourceScanner;
   import org.apache.tools.ant.types.EnumeratedAttribute;
  +import org.apache.tools.ant.types.FileSet;
   import org.apache.tools.ant.types.ZipFileSet;
   import org.apache.tools.zip.ZipOutputStream;
   
  @@ -521,7 +522,8 @@
        *         already); false if archive creation should proceed
        * @exception BuildException if it likes
        */
  -    protected boolean isUpToDate(FileScanner[] scanners, File zipFile)
  +    protected boolean isUpToDate(ResourceScanner[] scanners, 
  +                                 FileSet[] fss, File zipFile)
           throws BuildException {
           // need to handle manifest as a special check
           if (configuredManifest != null || manifestFile == null) {
  @@ -562,7 +564,7 @@
           } else if (manifestFile.lastModified() > zipFile.lastModified()) {
               return false;
           }
  -        return super.isUpToDate(scanners, zipFile);
  +        return super.isUpToDate(scanners, fss, zipFile);
       }
   
       protected boolean createEmptyZip(File zipFile) {
  @@ -585,6 +587,7 @@
                   manifest = null;
                   configuredManifest = savedConfiguredManifest;
                   filesetManifest = null;
  +                originalManifest = null;
               }
       }
   
  
  
  
  1.87      +88 -14    
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Zip.java
  
  Index: Zip.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Zip.java,v
  retrieving revision 1.86
  retrieving revision 1.87
  diff -u -r1.86 -r1.87
  --- Zip.java  9 Dec 2002 12:40:38 -0000       1.86
  +++ Zip.java  22 Jan 2003 12:36:41 -0000      1.87
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
  + * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -67,18 +67,25 @@
   import java.util.Vector;
   import java.util.zip.CRC32;
   import java.util.zip.ZipInputStream;
  +
   import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.DirectoryScanner;
   import org.apache.tools.ant.FileScanner;
   import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.ResourceScanner;
   import org.apache.tools.ant.types.EnumeratedAttribute;
   import org.apache.tools.ant.types.FileSet;
   import org.apache.tools.ant.types.PatternSet;
  +import org.apache.tools.ant.types.Resource;
  +import org.apache.tools.ant.types.ResourceFactory;
   import org.apache.tools.ant.types.ZipFileSet;
   import org.apache.tools.ant.types.ZipScanner;
  +import org.apache.tools.ant.util.FileNameMapper;
   import org.apache.tools.ant.util.FileUtils;
  +import org.apache.tools.ant.util.GlobPatternMapper;
  +import org.apache.tools.ant.util.IdentityMapper;
   import org.apache.tools.ant.util.MergingMapper;
  -import org.apache.tools.ant.util.SourceFileScanner;
  +import org.apache.tools.ant.util.SourceSelector;
   import org.apache.tools.zip.ZipEntry;
   import org.apache.tools.zip.ZipOutputStream;
   
  @@ -93,9 +100,11 @@
    *
    * @ant.task category="packaging"
    */
  -public class Zip extends MatchingTask {
  +public class Zip extends MatchingTask implements ResourceFactory {
   
       protected File zipFile;
  +    // use to scan own archive
  +    private ZipScanner zs;
       private File baseDir;
       protected Hashtable entries = new Hashtable();
       private Vector groupfilesets = new Vector();
  @@ -117,6 +126,7 @@
   
       protected boolean doubleFilePass = false;
       protected boolean skipWriting = false;
  +    private FileUtils fileUtils;
   
   
       /**
  @@ -331,22 +341,28 @@
   
           // Create the scanners to pass to isUpToDate().
           Vector dss = new Vector();
  +        Vector vfss = new Vector();
           if (baseDir != null) {
               dss.addElement(getDirectoryScanner(baseDir));
  +            FileSet fs = new FileSet();
  +            fs.setDir(baseDir);
  +            vfss.addElement(fs);
           }
           for (int i = 0; i < filesets.size(); i++) {
               FileSet fs = (FileSet) filesets.elementAt(i);
               dss.addElement (fs.getDirectoryScanner(getProject()));
  +            vfss.addElement(fs);
           }
           int dssSize = dss.size();
  -        FileScanner[] scanners = new FileScanner[dssSize];
  +        ResourceScanner[] scanners = new ResourceScanner[dssSize];
           dss.copyInto(scanners);
  -
  +        FileSet [] fss = new FileSet[dssSize];
  +        vfss.copyInto(fss);
           boolean success = false;
           try {
               // quick exit if the target is up to date
               // can also handle empty archives
  -            if (isUpToDate(scanners, zipFile)) {
  +            if (isUpToDate(scanners, fss, zipFile)) {
                   return;
               }
   
  @@ -642,6 +658,15 @@
           return true;
       }
   
  +    public Resource getResource(String name) {
  +        if (zs==null) {
  +            zs=new ZipScanner();
  +            // set the task of the zip scanner so that it can log properly
  +            zs.setTask(this);
  +            zs.setSrc(zipFile);
  +        }
  +        return zs.getResource(name);
  +    }
   
       /**
        * Check whether the archive is up-to-date; and handle behavior
  @@ -652,8 +677,17 @@
        *         already); false if archive creation should proceed
        * @exception BuildException if it likes
        */
  -    protected boolean isUpToDate(FileScanner[] scanners, File zipFile)
  +    protected boolean isUpToDate(ResourceScanner[] scanners, 
  +                                 FileSet[] fss, File zipFile)
           throws BuildException {
  +        Resource[][] resourceNames = grabResources(scanners);
  +        for (int counter = 0;counter < scanners.length; counter++){
  +            for (int j=0; j < resourceNames[counter].length;j++) {
  +                log("resource from scanner " + counter + " " + j + " name : "
  +                    + resourceNames[counter][j].getName(), 
Project.MSG_DEBUG);
  +            }
  +        }
  +
           String[][] fileNames = grabFileNames(scanners);
           File[] files = grabFiles(scanners, fileNames);
           if (files.length == 0) {
  @@ -681,17 +715,39 @@
                   return false;
               }
   
  -            SourceFileScanner sfs = new SourceFileScanner(this);
  -            MergingMapper mm = new MergingMapper();
  -            mm.setTo(zipFile.getAbsolutePath());
               for (int i = 0; i < scanners.length; i++) {
  -                if (sfs.restrict(fileNames[i], scanners[i].getBasedir(), 
null,
  -                                 mm).length > 0) {
  -                    return false;
  +                boolean result=false;
  +                FileNameMapper myMapper = new IdentityMapper();
  +                if (fss[i] instanceof ZipFileSet) {
  +                    ZipFileSet zfs = (ZipFileSet) fss[i];
  +                    if (zfs.getFullpath() != null
  +                        && !zfs.getFullpath().equals("") ) {
  +                        // in this case all files from origin map to
  +                        // the fullPath attribute of the zipfileset at
  +                        // destination
  +                        MergingMapper fm = new MergingMapper();
  +                        fm.setTo(zfs.getFullpath());
  +                        myMapper = fm;
  +
  +                    } else if (zfs.getPrefix() != null 
  +                               && !zfs.getPrefix().equals("")) {
  +                        GlobPatternMapper gm=new GlobPatternMapper();
  +                        gm.setFrom("*");
  +                        gm.setTo(zfs.getPrefix() + "*");
  +                        myMapper = gm;
  +                    }
  +                }
  +                Resource[] newerSources = 
  +                    SourceSelector.selectOutOfDateSources(this,
  +                                                          resourceNames[i],
  +                                                          myMapper, this);
  +                result = (newerSources.length == 0);
  +                if (!result) {
  +                    return result;
                   }
               }
  -            return true;
           }
  +        return true;
       }
   
       protected static File[] grabFiles(FileScanner[] scanners) {
  @@ -720,6 +776,24 @@
               result[i] = new String[files.length + dirs.length];
               System.arraycopy(files, 0, result[i], 0, files.length);
               System.arraycopy(dirs, 0, result[i], files.length, dirs.length);
  +        }
  +        return result;
  +    }
  +    /**
  +     *
  +     * @param scanners here are expected ResourceScanner arguments
  +     * @return double dimensional array of resources
  +     */
  +    protected static Resource[][] grabResources(ResourceScanner[] scanners) {
  +        Resource[][] result = new Resource[scanners.length][];
  +        for (int i = 0; i < scanners.length; i++) {
  +            Resource[] files = scanners[i].getIncludedFileResources();
  +            Resource[] directories = 
  +                scanners[i].getIncludedDirectoryResources();
  +            result[i] = new Resource[files.length + directories.length];
  +            System.arraycopy(files, 0, result[i], 0, files.length);
  +            System.arraycopy(directories, 0, result[i], files.length, 
  +                             directories.length);
           }
           return result;
       }
  
  
  
  1.7       +232 -17   
jakarta-ant/src/main/org/apache/tools/ant/types/ZipScanner.java
  
  Index: ZipScanner.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/types/ZipScanner.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ZipScanner.java   25 Jul 2002 15:21:21 -0000      1.6
  +++ ZipScanner.java   22 Jan 2003 12:36:41 -0000      1.7
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -55,18 +55,24 @@
   package org.apache.tools.ant.types;
   
   import java.io.File;
  +import java.io.FileInputStream;
  +import java.io.IOException;
  +import java.util.Vector;
  +import java.util.zip.ZipInputStream;
  +import java.util.zip.ZipEntry;
  +import java.util.zip.ZipException;
  +
   import org.apache.tools.ant.DirectoryScanner;
  +import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.Task;
   
   /**
    * ZipScanner accesses the pattern matching algorithm in DirectoryScanner,
    * which are protected methods that can only be accessed by subclassing.
    *
    * This implementation of FileScanner defines getIncludedFiles to return
  - * only the Zip File which is being scanned, not the matching Zip entries.
  - * Arguably, it should return the matching entries, however this would
  - * complicate existing code which assumes that FileScanners return a
  - * set of file system files that can be accessed directly.
  - * 
  + * the matching Zip entries.
  + *
    * @author Don Ferguson <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
    */
   public class ZipScanner extends DirectoryScanner {
  @@ -75,35 +81,84 @@
        * The zip file which should be scanned.
        */
       protected File srcFile;
  +    /**
  +     *  The current task, used to report errors, ...
  +     */
  +    private Task task;
  +    /**
  +     * to record the last scanned zip file with its modification date
  +     */
  +    private Resource lastScannedResource;
  +    /**
  +     * record list of all zip entries
  +     */
  +    private Vector myentries;
   
       /**
  -     * Sets the srcFile for scanning. This is the jar or zip file that is 
scanned
  -     * for matching entries.
  +     * Sets the srcFile for scanning. This is the jar or zip file that
  +     * is scanned for matching entries.
        *
        * @param srcFile the (non-null) zip file name for scanning
        */
       public void setSrc(File srcFile) {
           this.srcFile = srcFile;
       }
  +    /**
  +     * Sets the current task. This is used to provide proper logging
  +     * for exceptions
  +     *
  +     * @param task the current task
  +     *
  +     * @since Ant 1.5.2
  +     */
  +    public void setTask(Task task) {
  +        this.task = task;
  +    }
   
       /**
  -     * Returns the zip file itself, not the matching entries within the zip 
file.
  -     * This keeps the uptodate test in the Zip task simple; otherwise we'd 
need
  -     * to treat zip filesets specially.
  +     * Returns the names of the files which matched at least one of the
  +     * include patterns and none of the exclude patterns.
  +     * The names are relative to the base directory.
        *
  -     * @return the source file from which entries will be extracted.
  +     * @return the names of the files which matched at least one of the
  +     *         include patterns and none of the exclude patterns.
        */
       public String[] getIncludedFiles() {
  -        String[] result = new String[1];
  -        result[0] = srcFile.getAbsolutePath();
  -        return result;
  +        Vector myvector = new Vector();
  +        // first check if the archive needs to be scanned again
  +        scanme();
  +        for (int counter = 0; counter < myentries.size(); counter++) {
  +            Resource myresource= (Resource) myentries.elementAt(counter);
  +            if (!myresource.isDirectory() && match(myresource.getName())) {
  +                myvector.addElement(myresource.getName());
  +            }
  +        }
  +        String[] files = new String[myvector.size()];
  +        myvector.copyInto(files);
  +        return files;
       }
   
       /**
  -     * Returns an empty list of directories to create.
  +     * Returns the names of the directories which matched at least one of the
  +     * include patterns and none of the exclude patterns.
  +     * The names are relative to the base directory.
  +     *
  +     * @return the names of the directories which matched at least one of the
  +     * include patterns and none of the exclude patterns.
        */
       public String[] getIncludedDirectories() {
  -        return new String[0];
  +        Vector myvector=new Vector();
  +        // first check if the archive needs to be scanned again
  +        scanme();
  +        for (int counter = 0; counter < myentries.size(); counter++) {
  +            Resource myresource = (Resource) myentries.elementAt(counter);
  +            if (myresource.isDirectory() && match(myresource.getName())) {
  +                myvector.addElement(myresource.getName());
  +            }
  +        }
  +        String[] files = new String[myvector.size()];
  +        myvector.copyInto(files);
  +        return files;
       }
   
       /**
  @@ -135,4 +190,164 @@
           return isIncluded(vpath) && !isExcluded(vpath);
       }
   
  +    /**
  +     * Returns the resources of the files which matched at least one of the
  +     * include patterns and none of the exclude patterns.
  +     * The names are relative to the base directory.
  +     *
  +     * @return resource information for the files which matched at
  +     * least one of the include patterns and none of the exclude
  +     * patterns.
  +     *
  +     * @since Ant 1.5.2
  +     */
  +    public Resource[] getIncludedFileResources() {
  +        Vector myvector = new Vector();
  +        // first check if the archive needs to be scanned again
  +        scanme();
  +        for (int counter = 0; counter < myentries.size(); counter++) {
  +             Resource myresource = (Resource) myentries.elementAt(counter);
  +             if (!myresource.isDirectory() && match(myresource.getName())) {
  +                 myvector.addElement(myresource.clone());
  +             }
  +         }
  +         Resource[] resources = new Resource[myvector.size()];
  +         myvector.copyInto(resources);
  +         return resources;
  +    }
  +
  +    /**
  +     * Returns the resources of the files which matched at least one of the
  +     * include patterns and none of the exclude patterns.
  +     * The names are relative to the base directory.
  +     *
  +     * @return resource information for the files which matched at
  +     * least one of the include patterns and none of the exclude
  +     * patterns.
  +     *
  +     * @since Ant 1.5.2
  +     */
  +    public Resource[] getIncludedDirectoryResources() {
  +        Vector myvector = new Vector();
  +         // first check if the archive needs to be scanned again
  +         scanme();
  +         for (int counter = 0; counter < myentries.size(); counter++) {
  +             Resource myresource = (Resource) myentries.elementAt(counter);
  +             if (myresource.isDirectory() && match(myresource.getName())) {
  +                 myvector.add(myresource.clone());
  +             }
  +         }
  +         Resource[] resources = new Resource[myvector.size()];
  +         myvector.copyInto(resources);
  +         return resources;
  +    }
  +
  +    /**
  +     * @param name path name of the file sought in the archive
  +     *
  +     * @since Ant 1.5.2
  +     */
  +    public Resource getResource(String name) {
  +        // first check if the archive needs to be scanned again
  +        scanme();
  +        for (int counter = 0; counter < myentries.size(); counter++) {
  +            Resource myresource=(Resource)myentries.elementAt(counter);
  +            if (myresource.getName().equals(name)) {
  +                return myresource;
  +            }
  +        }
  +        return new Resource(name);
  +    }
  +
  +    /**
  +     * if the datetime of the archive did not change since
  +     * lastScannedResource was initialized returns immediately else if
  +     * the archive has not been scanned yet, then all the zip entries
  +     * are put into the vector myentries as a vector of the resource
  +     * type
  +     */
  +    private void scanme() {
  +        Resource thisresource = new Resource(srcFile.getAbsolutePath(),
  +                                             srcFile.exists(),
  +                                             srcFile.lastModified());
  +
  +        // spare scanning again and again
  +        if (lastScannedResource != null 
  +            && lastScannedResource.getName().equals(thisresource.getName())
  +            && lastScannedResource.getLastModified() 
  +               == thisresource.getLastModified()) {
  +            return;
  +        }
  +
  +        Vector vResult = new Vector();
  +        if (task != null) {
  +            task.log("checking zip entries: " + srcFile, 
Project.MSG_VERBOSE);
  +        }
  +
  +        ZipEntry entry = null;
  +        ZipInputStream in = null;
  +        myentries = new Vector();
  +        try {
  +            try {
  +                in = new ZipInputStream(new FileInputStream(srcFile));
  +                if (task != null) {
  +                    task.log("opening input stream from " + srcFile, 
  +                             Project.MSG_DEBUG);
  +                }
  +            } catch (IOException ex) {
  +                // XXX - throw a BuildException instead ??
  +                if (task != null) {
  +                    task.log("problem opening "+srcFile,Project.MSG_ERR);
  +                }
  +            }
  +            
  +            while (true) {
  +                try {
  +                    entry = in.getNextEntry();
  +                    if (entry == null) {
  +                        break;
  +                    }
  +                    myentries.add(new Resource(entry.getName(),
  +                                               true,
  +                                               entry.getTime(),
  +                                               entry.isDirectory()));
  +                    if (task != null) {
  +                        task.log("adding entry " + entry.getName() + " from "
  +                                 + srcFile, Project.MSG_DEBUG);
  +                    }
  +                    
  +                } catch (ZipException ex) {
  +                    // XXX - throw a BuildException instead ??
  +                    if (task != null ) {
  +                        task.log("problem reading " + srcFile,
  +                                 Project.MSG_ERR);
  +                    }
  +
  +                } catch (IOException e) {
  +                    // XXX - throw a BuildException instead ??
  +                    if (task != null) {
  +                        task.log("problem reading zip entry from " + srcFile,
  +                                 Project.MSG_ERR);
  +                    }
  +                }
  +            }
  +        } finally {
  +            if (in != null) {
  +                try {
  +                    in.close();
  +                    if (task != null) {
  +                        task.log("closing input stream from " + srcFile,
  +                                 Project.MSG_DEBUG);
  +                    }
  +                } catch (IOException ex) {
  +                    if (task != null) {
  +                        task.log("problem closing input stream from "
  +                                 + srcFile, Project.MSG_ERR);
  +                    }
  +                }
  +            }
  +        }
  +        // record data about the last scanned resource
  +        lastScannedResource = thisresource;
  +    }
   }
  
  
  
  1.1                  
jakarta-ant/src/main/org/apache/tools/ant/types/Resource.java
  
  Index: Resource.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.tools.ant.types;
  
  /**
   * describes a File or a ZipEntry
   *
   * this class is meant to be used by classes needing to record path
   * and date/time information about a file, a zip entry or some similar
   * resource (URL, archive in a version control repository, ...)
   *
   * @since Ant 1.5.2
   */
  public class Resource implements Cloneable {
      private String name = null;
      private boolean exists = true;
      private long lastmodified = 0;
      private boolean directory = false;
  
      /**
       * default constructor
       */
      public Resource() {
      }
  
      /**
       * only sets the name.
       *
       * <p>This is a dummy, used for not existing resources.</p>
       */
      public Resource(String name) {
          this(name, false, 0, false);
      }
  
      /**
       * sets the name, lastmodified flag, and exists flag
       */
      public Resource(String name, boolean exists, long lastmodified) {
          this(name, exists, lastmodified, false);
      }
  
      public Resource(String name, boolean exists, long lastmodified,
                      boolean directory) {
          this.name = name;
          this.exists = exists;
          this.lastmodified = lastmodified;
          this.directory = directory;
      }
  
      /**
       * name attribute will contain the path of a file relative to the
       * root directory of its fileset or the recorded path of a zip
       * entry.
       *
       * <p>example for a file with fullpath /var/opt/adm/resource.txt
       * in a file set with root dir /var/opt it will be
       * adm/resource.txt.</p>
       */
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
      /**
       * the exists attribute tells whether a file exists
       */
      public boolean isExists() {
          return exists;
      }
  
      public void setExists(boolean exists) {
          this.exists = exists;
      }
  
      /**
       * tells the modification time in milliseconds since 01.01.1970 of
       *
       * @return 0 if the resource does not exist to mirror the behavior
       * of [EMAIL PROTECTED] java.io.File File}.
       */
      public long getLastModified() {
          return !exists || lastmodified < 0 ? 0 : lastmodified;
      }
  
      public void setLastModified(long lastmodified) {
          this.lastmodified = lastmodified;
      }
      /**
       * tells if the resource is a directory
       * @return boolean flag indicating if the resource is a directory
       */
      public boolean isDirectory() {
          return directory;
      }
  
      public void setDirectory(boolean directory) {
          this.directory = directory;
      }
  
      /**
       * @return copy of this
       */
      public Object clone() {
          try {
              return super.clone();
          } catch (CloneNotSupportedException e) {
              throw new Error("CloneNotSupportedException for a "
                              + "Clonable Resource caught?");
          }
      }
  
  }
  
  
  
  1.1                  
jakarta-ant/src/main/org/apache/tools/ant/types/ResourceFactory.java
  
  Index: ResourceFactory.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.tools.ant.types;
  
  /**
   * this interface should be implemented by classes (Scanners) needing
   * to deliver information about resources.
   *
   * @since Ant 1.5.2
   */
  public interface ResourceFactory {
  
      /**
       * Query a resource (file, zipentry, ...) by name
       *
       * @param Name relative path of the resource about which
       * information is sought
       * @return instance of Resource; the exists attribute of Resource
       * will tell whether the sought resource exists
       */
      Resource getResource(String name);
  }
  
  
  
  1.15      +34 -62    
jakarta-ant/src/main/org/apache/tools/ant/util/SourceFileScanner.java
  
  Index: SourceFileScanner.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/util/SourceFileScanner.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- SourceFileScanner.java    25 Jul 2002 15:21:24 -0000      1.14
  +++ SourceFileScanner.java    22 Jan 2003 12:36:41 -0000      1.15
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
  + * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -58,6 +58,8 @@
   import java.util.Vector;
   import org.apache.tools.ant.Project;
   import org.apache.tools.ant.Task;
  +import org.apache.tools.ant.types.ResourceFactory;
  +import org.apache.tools.ant.types.Resource;
   import org.apache.tools.ant.taskdefs.condition.Os;
   
   /**
  @@ -70,11 +72,12 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Stefan Bodewig</a>
    */
  -public class SourceFileScanner {
  +public class SourceFileScanner implements ResourceFactory {
   
       protected Task task;
   
       private FileUtils fileUtils;
  +    private File destDir;     // base directory of the fileset
   
       /**
        * @param task The task we should log messages through
  @@ -97,71 +100,26 @@
        */
       public String[] restrict(String[] files, File srcDir, File destDir,
                                FileNameMapper mapper) {
  -
  -        long now = (new java.util.Date()).getTime();
  -        StringBuffer targetList = new StringBuffer();
  -
  -        /*
  -          If we're on Windows, we have to munge the time up to 2 secs to
  -          be able to check file modification times.
  -          (Windows has a max resolution of two secs for modification times)
  -          Actually this is a feature of the FAT file system, NTFS does
  -          not have it, so if we could reliably passively test for an NTFS
  -          file systems we could turn this off...
  -        */
  -        if (Os.isFamily("windows")) {
  -            now += 2000;
  -        }
  -
  +        // record destdir for later use in getResource
  +        this.destDir = destDir;
           Vector v = new Vector();
           for (int i = 0; i < files.length; i++) {
  -
  -            String[] targets = mapper.mapFileName(files[i]);
  -            if (targets == null || targets.length == 0) {
  -                task.log(files[i] + " skipped - don\'t know how to handle 
it",
  -                         Project.MSG_VERBOSE);
  -                continue;
  -            }
  -
               File src = fileUtils.resolveFile(srcDir, files[i]);
  +            v.addElement(new Resource(files[i], src.exists(),
  +                                      src.lastModified(), 
src.isDirectory()));
  +        }
  +        Resource[] sourceresources= new Resource[v.size()];
  +        v.copyInto(sourceresources);
   
  -            if (src.lastModified() > now) {
  -                task.log("Warning: " + files[i] + " modified in the 
future.", 
  -                         Project.MSG_WARN);
  -            }
  -
  -            boolean added = false;
  -            targetList.setLength(0);
  -            for (int j = 0; !added && j < targets.length; j++) {
  -                File dest = fileUtils.resolveFile(destDir, targets[j]);
  -                
  -                if (!dest.exists()) {
  -                    task.log(files[i] + " added as " + dest.getAbsolutePath()
  -                        + " doesn\'t exist.", Project.MSG_VERBOSE);
  -                    v.addElement(files[i]);
  -                    added = true;
  -                } else if (src.lastModified() > dest.lastModified()) {
  -                    task.log(files[i] + " added as " + dest.getAbsolutePath()
  -                        + " is outdated.", Project.MSG_VERBOSE);
  -                    v.addElement(files[i]);
  -                    added = true;
  -                } else {
  -                    if (targetList.length() > 0) {
  -                        targetList.append(", ");
  -                    }
  -                    targetList.append(dest.getAbsolutePath());
  -                }
  -            }
  -
  -            if (!added) {
  -                task.log(files[i] + " omitted as " + targetList.toString()
  -                         + (targets.length == 1 ? " is" : " are ")
  -                         + " up to date.", Project.MSG_VERBOSE);
  -            }
  -            
  +        // build the list of sources which are out of date with
  +        // respect to the target
  +        Resource[] outofdate = 
  +            SourceSelector.selectOutOfDateSources(task, sourceresources,
  +                                                  mapper, this);
  +        String[] result = new String[outofdate.length];
  +        for (int counter=0; counter < outofdate.length; counter++) {
  +            result[counter] = outofdate[counter].getName();
           }
  -        String[] result = new String[v.size()];
  -        v.copyInto(result);
           return result;
       }
   
  @@ -179,4 +137,18 @@
           }
           return result;
       }
  +
  +    /**
  +     * returns resource information for a file at destination
  +     * @param name relative path of file at destination
  +     * @return data concerning a file whose relative path to destDir is name
  +     *
  +     * @since Ant 1.5.2
  +     */
  +    public Resource getResource(String name) {
  +        File src = fileUtils.resolveFile(destDir, name);
  +        return new Resource(name, src.exists(), src.lastModified(),
  +                            src.isDirectory());
  +    }
   }
  +
  
  
  
  1.1                  
jakarta-ant/src/main/org/apache/tools/ant/util/SourceSelector.java
  
  Index: SourceSelector.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.tools.ant.util;
  
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.ProjectComponent;
  import org.apache.tools.ant.taskdefs.condition.Os;
  import org.apache.tools.ant.types.Resource;
  import org.apache.tools.ant.types.ResourceFactory;
  
  import java.util.Vector;
  
  /**
   * this class provides utilily methods to process resources
   *
   * @since Ant 1.5.2
   */
  public class SourceSelector {
  
      /**                                                                      {
       * tells which source files should be reprocessed based on the
       * last modification date of target files
       * @param logTo where to send (more or less) interesting output
       * @param source array of resources bearing relative path and last
       * modification date
       * @param mapper filename mapper indicating how to find the target
       * files
       * @param targets object able to map as a resource a relative path
       * at <b>destination</b>
       * @return array containing the source files which need to be
       * copied or processed, because the targets are out of date or do
       * not exist
       */
      public static Resource[] selectOutOfDateSources(ProjectComponent logTo,
                                                      Resource[] source,
                                                      FileNameMapper mapper,
                                                      ResourceFactory targets) {
          long now = (new java.util.Date()).getTime();
          StringBuffer targetList = new StringBuffer();
  
          /*
            If we're on Windows, we have to munge the time up to 2 secs to
            be able to check file modification times.
            (Windows has a max resolution of two secs for modification times)
            Actually this is a feature of the FAT file system, NTFS does
            not have it, so if we could reliably passively test for an NTFS
            file systems we could turn this off...
          */
          if (Os.isFamily("windows")) {
              now += 2000;
          }
  
          Vector vresult = new Vector();
          for (int counter = 0; counter < source.length; counter++) {
              if (source[counter].getLastModified() > now) {
                  logTo.log("Warning: " + source[counter].getName() 
                           + " modified in the future.", 
                           Project.MSG_WARN);
              }
  
              String[] targetnames = 
                  mapper.mapFileName(source[counter].getName());
              if (targetnames != null) {
                  boolean added = false;
                  targetList.setLength(0);
                  for (int ctarget = 0; ctarget < targetnames.length; 
ctarget++) {
                      Resource atarget = 
                          targets.getResource(targetnames[ctarget]);
                      // if the target does not exist, or exists and
                      // is older than the source, then we want to
                      // add the resource to what needs to be copied
                      if (!atarget.isExists()) {
                          logTo.log(source[counter].getName() + " added as " 
                                    + atarget.getName()
                                    + " doesn\'t exist.", Project.MSG_VERBOSE);
                          vresult.addElement(source[counter]);
                          added = true;
                      } else if (atarget.getLastModified() 
                                 < source[counter].getLastModified()) {
                          logTo.log(source[counter].getName() + " added as " 
                                    + atarget.getName()
                                    + " is outdated.", Project.MSG_VERBOSE);
                          vresult.addElement(source[counter]);
                          added = true;
                      } else {
                          if (targetList.length() > 0) {
                              targetList.append(", ");
                          }
                          targetList.append(atarget.getName());
                      }
                  }
  
                  if (!added) {
                      logTo.log(source[counter].getName() 
                                + " omitted as " + targetList.toString()
                                + (targetnames.length == 1 ? " is" : " are ")
                                + " up to date.", Project.MSG_VERBOSE);
                  }
              } else {
                  logTo.log(source[counter].getName() 
                            + " skipped - don\'t know how to handle it",
                            Project.MSG_VERBOSE);
              }
          }
          Resource[] result= new Resource[vresult.size()];
          vresult.copyInto(result);
          return result;
      }
  }
  
  
  
  1.9       +2 -2      
jakarta-ant/src/main/org/apache/tools/zip/ZipOutputStream.java
  
  Index: ZipOutputStream.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/zip/ZipOutputStream.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ZipOutputStream.java      6 Dec 2002 16:17:36 -0000       1.8
  +++ ZipOutputStream.java      22 Jan 2003 12:36:41 -0000      1.9
  @@ -653,7 +653,7 @@
               |         (time.getDate() << 16)
               |         (time.getHours() << 11)
               |         (time.getMinutes() << 5)
  -            |         (time.getSeconds() >> 1);
  +            |         ((time.getSeconds() + 2) >> 1);
           
           byte[] result = new byte[4];
           result[0] = (byte) ((value & 0xFF));
  
  
  
  1.12      +4 -4      
jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/JarTest.java
  
  Index: JarTest.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/JarTest.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- JarTest.java      17 Jan 2003 12:30:44 -0000      1.11
  +++ JarTest.java      22 Jan 2003 12:36:41 -0000      1.12
  @@ -119,20 +119,20 @@
                        jarModifiedDate, jarFile.lastModified());
       }
   
  -    public void XtestRecreateWithoutUpdateAdditionalFiles() {
  +    public void testRecreateWithoutUpdateAdditionalFiles() {
           testRecreate("test4", "testRecreateWithoutUpdateAdditionalFiles");
       }
   
  -    public void XtestRecreateWithUpdateAdditionalFiles() {
  +    public void testRecreateWithUpdateAdditionalFiles() {
           testRecreate("test4", "testRecreateWithUpdateAdditionalFiles");
       }
   
  -    public void XtestRecreateWithoutUpdateNewerFile() {
  +    public void testRecreateWithoutUpdateNewerFile() {
           testRecreate("testRecreateNewerFileSetup",
                        "testRecreateWithoutUpdateNewerFile");
       }
   
  -    public void XtestRecreateWithUpdateNewerFile() {
  +    public void testRecreateWithUpdateNewerFile() {
           testRecreate("testRecreateNewerFileSetup",
                        "testRecreateWithUpdateNewerFile");
       }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to