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]>