stevel 2004/11/18 08:00:18 Modified: src/main/org/apache/tools/ant/taskdefs/optional/repository Repository.java Library.java MavenRepository.java HttpRepository.java RepositoryRef.java GetLibraries.java src/etc/testcases/taskdefs/optional getlibraries.xml src/testcases/org/apache/tools/ant/taskdefs/optional/repository GetLibrariesTest.java src/main/org/apache/tools/ant/taskdefs Get.java Added: src/main/org/apache/tools/ant/taskdefs/repository EnabledLibraryElement.java ScheduledUpdatePolicy.java EnabledLibraryElementList.java AbsentFilesPolicy.java TimestampPolicy.java BaseLibraryPolicy.java LibraryPolicy.java ForceUpdatePolicy.java NoUpdatePolicy.java AssertDownloaded.java Log: Updated <getlibraries> code, plus new classes. After this checkin I'm about to move and rename some of the existing stuff. Revision Changes Path 1.3 +9 -2 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/Repository.java Index: Repository.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/Repository.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Repository.java 2 Nov 2004 23:37:21 -0000 1.2 +++ Repository.java 18 Nov 2004 16:00:17 -0000 1.3 @@ -99,11 +99,18 @@ /** * fetch a library from the repository * - * @param library + * @param library library to fetch * + * @param useTimestamp flag to indicate the timestamp of the lib should be used * @return */ - public abstract boolean fetch(Library library) throws IOException; + public abstract boolean fetch(Library library, boolean useTimestamp) throws IOException; + /** + * this is a string that uniquely describes the repository + * and can be used for equality tests <i>across</i> instances. + * @return + */ + public abstract String getRepositoryURI(); } 1.3 +126 -52 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/Library.java Index: Library.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/Library.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Library.java 30 Oct 2004 21:03:44 -0000 1.2 +++ Library.java 18 Nov 2004 16:00:17 -0000 1.3 @@ -18,8 +18,9 @@ package org.apache.tools.ant.taskdefs.optional.repository; import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.repository.EnabledLibraryElement; import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.FileUtils; import java.io.File; @@ -28,7 +29,30 @@ * * @since Ant1.7 */ -public class Library { +public class Library implements EnabledLibraryElement { + + /** + * enabled flag + */ + private boolean enabled = true; + + /** + * turn policy on/off + * + * @param enabled + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + /** + * are we enabled + * + * @return true if [EMAIL PROTECTED] #enabled} is set + */ + public boolean getEnabled() { + return enabled; + } //project "ant" private String project; @@ -52,14 +76,12 @@ private File libraryFile; /** - * if clause + * we fetch every library by default; note the enabled/disabled + * flag has precedence, and this flag is not visible in the XML */ - private String ifClause; + private boolean toFetch=true; - /** - * unless clause - */ - private String unlessClause; + private boolean fetched=false; public static final String ERROR_NO_ARCHIVE = "No archive defined"; public static final String ERROR_NO_PROJECT = "No project defined"; @@ -70,6 +92,7 @@ * suffix */ private String suffix = "jar"; + public static final String ERROR_FILE_IS_A_DIR = "Library file is a directory:"; /** @@ -155,38 +178,6 @@ } /** - * a property that must be set for the library to be considered a dependency - * @return - */ - public String getIf() { - return ifClause; - } - - /** - * a property that must be set for the library to be considered a dependency - * @param ifClause - */ - public void setIf(String ifClause) { - this.ifClause = ifClause; - } - - /** - * a property that must be unset for the library to be considered a dependency - * @return - */ - public String getUnless() { - return unlessClause; - } - - /** - * a property that must be unset for the library to be considered a dependency - * @param unlessClause - */ - public void setUnless(String unlessClause) { - this.unlessClause = unlessClause; - } - - /** * get the library file * (only non-null after binding) * @return library file or null @@ -196,6 +187,14 @@ } /** + * set the library file. + * @param libraryFile + */ + public void setLibraryFile(File libraryFile) { + this.libraryFile = libraryFile; + } + + /** * fault if the field is null or empty * * @param field @@ -241,10 +240,16 @@ */ public void bind(File baseDir) { validate(); + FileUtils fileUtils=FileUtils.newFileUtils(); + if (destinationName == null) { - destinationName = getNormalFilename(); + destinationName = getMavenPath('/'); + } + libraryFile = fileUtils.resolveFile(baseDir, destinationName); + if(libraryFile.isDirectory()) { + throw new BuildException(ERROR_FILE_IS_A_DIR + +libraryFile); } - libraryFile = new File(baseDir, destinationName); } /** @@ -310,21 +315,40 @@ return libraryFile.getAbsolutePath(); } + /** - * test for being enabled - * @param project + * prefixed to avoid ant picking up on it, this sets + * the fetch/no-fetch flag. + * @param toFetch + */ + public void _setToFetch(boolean toFetch) { + this.toFetch = toFetch; + } + + /** + * get the fetch flag. * @return */ - public boolean isEnabled(Project project) { - if (unlessClause != null && project.getProperty(unlessClause) != null) { - return false; - } - if (ifClause == null) { - return true; - } - return project.getProperty(ifClause) != null; + public boolean isToFetch() { + return toFetch; } + /** + * get a flag that marks if a file is fetched + * @return + */ + public boolean wasFetched() { + return fetched; + } + + /** + * another not-for-end-users attribute; a flag set to true if the + * library has been fetched. + * @param fetched + */ + public void _setFetched(boolean fetched) { + this.fetched = fetched; + } /** * add our location to a filepath @@ -335,5 +359,55 @@ pathElement.setLocation(getLibraryFile()); } + /** + * equality test uses archive, destinationName, project, suffix and version + * fields (any of which can be null) + * @param o + * @return + */ + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Library)) { + return false; + } + + final Library library = (Library) o; + + if (archive != null ? !archive.equals(library.archive) : library.archive != null) { + return false; + } + if (destinationName != null ? !destinationName.equals( + library.destinationName) : library.destinationName != null) { + return false; + } + if (project != null ? !project.equals(library.project) : library.project != null) { + return false; + } + if (suffix != null ? !suffix.equals(library.suffix) : library.suffix != null) { + return false; + } + if (version != null ? !version.equals(library.version) : library.version != null) { + return false; + } + + return true; + } + + /** + * Hash code uses the name fields as [EMAIL PROTECTED] #equals(Object)} + * This sequence + * @return + */ + public int hashCode() { + int result; + result = (project != null ? project.hashCode() : 0); + result = 29 * result + (version != null ? version.hashCode() : 0); + result = 29 * result + (archive != null ? archive.hashCode() : 0); + result = 29 * result + (destinationName != null ? destinationName.hashCode() : 0); + result = 29 * result + (suffix != null ? suffix.hashCode() : 0); + return result; + } } 1.3 +14 -6 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/MavenRepository.java Index: MavenRepository.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/MavenRepository.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- MavenRepository.java 2 Nov 2004 23:37:21 -0000 1.2 +++ MavenRepository.java 18 Nov 2004 16:00:17 -0000 1.3 @@ -19,10 +19,9 @@ import org.apache.tools.ant.util.FileUtils; -import java.io.IOException; import java.io.File; import java.io.FileInputStream; -import java.io.FileReader; +import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; @@ -91,17 +90,28 @@ } /** + * this is a string that uniquely describes the repository and can be used + * for equality tests <i>across</i> instances. + * + * @return maven identifier + */ + public String getRepositoryURI() { + return "maven://" + getUrl(); + } + + /** * fetch a library from the repository * * @param library * + * @param useTimestamp * @return true if we retrieved * * @throws org.apache.tools.ant.BuildException * */ - public boolean fetch(Library library) throws IOException { - boolean fetched=super.fetch(library); + public boolean fetch(Library library, boolean useTimestamp) throws IOException { + boolean fetched=super.fetch(library, useTimestamp); if(fetched && checkMD5) { //we got here if there was a fetch. so we now get the MD5 info from the file, boolean successful=false; @@ -140,5 +150,3 @@ } } - -// e1b1720a761ca36eaa47e1c7d802e676 \ No newline at end of file 1.4 +19 -64 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/HttpRepository.java Index: HttpRepository.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/HttpRepository.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- HttpRepository.java 2 Nov 2004 23:37:21 -0000 1.3 +++ HttpRepository.java 18 Nov 2004 16:00:17 -0000 1.4 @@ -68,8 +68,6 @@ * retry logic */ public static final String ERROR_REENTRANT_USE = "Repository is already in use"; - private static final String IF_MODIFIED_SINCE = "If-Modified-Since"; - private static final int BLOCKSIZE = 8192; /** * get the base URL of the repository @@ -169,9 +167,9 @@ url = url + '/'; } - //validate the URL - URL repository; try { + //validate the URL + URL repository; repository = new URL(url); } catch (MalformedURLException e) { throw new BuildException(e); @@ -213,12 +211,13 @@ * * @param library * + * @param useTimestamp * @return true if we retrieved * * @throws org.apache.tools.ant.BuildException * */ - public boolean fetch(Library library) throws IOException { + public boolean fetch(Library library, boolean useTimestamp) throws IOException { String path = getRemoteLibraryURL(library); logVerbose("Library URL=" + path); @@ -226,11 +225,9 @@ logVerbose("destination =" + library.getAbsolutePath()); long start, finish; start = System.currentTimeMillis(); - finish = System.currentTimeMillis(); - boolean useTimestamps = !getOwner().isForceDownload() && - !library.exists(); - boolean success=get(remoteURL, library.getLibraryFile(),useTimestamps, + boolean success=get(remoteURL, library.getLibraryFile(),useTimestamp, username, password); + finish = System.currentTimeMillis(); long diff = finish - start; logVerbose("downloaded in " + diff / 1000 + " seconds"); @@ -246,9 +243,11 @@ */ public boolean get(URL url,File destFile,boolean useTimestamp,String user,String passwd) throws IOException { + //create the destination dir + destFile.getParentFile().mkdirs(); Get getTask = new Get(); getTask.setProject(getProject()); - getTask.setTaskName("dependencies"); + getTask.setTaskName(owner.getTaskName()); getTask.setDest(destFile); getTask.setUsername(user); getTask.setPassword(passwd); @@ -287,65 +286,21 @@ protected abstract String getRemoteLibraryURL(Library library); /** - * save a stream from a connection to a library. prerequisite: connection - * open and response=200. - * - * @param get - * @param library - * - * @throws java.io.IOException on any trouble. + * Returns a string representation of the repository + * Used for scheduled updates. + * @return the base URL */ - /* - protected void saveStreamToLibrary(GetMethod get, Library library) - throws IOException { - //we only get here if we are happy - //so save it to a temp file - File tempDest = File.createTempFile("download", ".bin", getOwner() - .getDestDir()); - logDebug("Saving file to " + tempDest); - FileOutputStream fos = new FileOutputStream(tempDest); - InputStream is = get.getResponseBodyAsStream(); - boolean finished = false; - try { - byte[] buffer = new byte[BLOCKSIZE]; - int length; - - while ((length = is.read(buffer)) >= 0) { - fos.write(buffer, 0, length); - } - finished = true; - } finally { - FileUtils.close(fos); - FileUtils.close(is); - // we have started to (over)write dest, but failed. - // Try to delete the garbage we'd otherwise leave - // behind. - if (!finished) { - logVerbose("Deleting temporary file after failed download"); - tempDest.delete(); - } - } - logDebug("download complete; renaming destination file"); - //then copy over the file - File libraryFile = library.getLibraryFile(); - if (libraryFile.exists()) { - libraryFile.delete(); - } - // set the dest file - if (!tempDest.renameTo(libraryFile)) { - tempDest.delete(); - throw new IOException( - "Could not rename temp file to destination file"); - } + public String toString() { + return "Repository at " + getUrl(); } - */ /** - * Returns a string representation of the repository + * this is a string that uniquely describes the repository and can be used + * for equality tests <i>across</i> instances. * - * @return the base URL + * @return */ - public String toString() { - return "Repository at " + getUrl(); + public String getRepositoryURI() { + return "HttpRepository://"+getUrl(); } } 1.3 +11 -1 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/RepositoryRef.java Index: RepositoryRef.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/RepositoryRef.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- RepositoryRef.java 2 Nov 2004 23:37:21 -0000 1.2 +++ RepositoryRef.java 18 Nov 2004 16:00:17 -0000 1.3 @@ -70,10 +70,20 @@ * * @param library * + * @param useTimestamp * @return */ - public boolean fetch(Library library) throws IOException { + public boolean fetch(Library library, boolean useTimestamp) throws IOException { throw new BuildException(E_NOTIMPL); } + /** + * this is a string that uniquely describes the repository and can be used + * for equality tests <i>across</i> instances. + * + * @return + */ + public String getRepositoryURI() { + return "ref://"+getRefid(); + } } 1.4 +293 -131 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/GetLibraries.java Index: GetLibraries.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/GetLibraries.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- GetLibraries.java 2 Nov 2004 23:37:21 -0000 1.3 +++ GetLibraries.java 18 Nov 2004 16:00:17 -0000 1.4 @@ -19,16 +19,23 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.repository.AbsentFilesPolicy; +import org.apache.tools.ant.taskdefs.repository.AssertDownloaded; +import org.apache.tools.ant.taskdefs.repository.EnabledLibraryElementList; +import org.apache.tools.ant.taskdefs.repository.ForceUpdatePolicy; +import org.apache.tools.ant.taskdefs.repository.LibraryPolicy; +import org.apache.tools.ant.taskdefs.repository.NoUpdatePolicy; +import org.apache.tools.ant.taskdefs.repository.ScheduledUpdatePolicy; +import org.apache.tools.ant.taskdefs.repository.TimestampPolicy; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; import java.io.File; import java.io.IOException; -import java.util.Collection; +import java.util.ArrayList; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; -import java.util.NoSuchElementException; +import java.util.ListIterator; /** * This task will retrieve one or more libraries from a repository. <ol> @@ -39,7 +46,7 @@ * @ant.task * @since Ant 1.7 */ -public class GetLibraries extends Task { +public final class GetLibraries extends Task { /** * destination @@ -47,11 +54,6 @@ private File destDir; /** - * flag to force a download - */ - private boolean forceDownload = false; - - /** * flag to force offline */ private boolean offline = false; @@ -59,7 +61,12 @@ /** * list of libraries */ - private List libraries = new LinkedList(); + private EnabledLibraryElementList libraries = new EnabledLibraryElementList(); + + /** + * helper list + */ + private EnabledLibraryElementList policies=new EnabledLibraryElementList(); /** * repository for retrieval @@ -72,16 +79,33 @@ */ private String pathid; - + /** + * should we be timestamp aware in downloads? + */ + private boolean useTimestamp = false; public static final String ERROR_ONE_REPOSITORY_ONLY = "Only one repository is allowed"; public static final String ERROR_NO_DEST_DIR = "No destination directory"; public static final String ERROR_NO_REPOSITORY = "No repository defined"; - public static final String ERROR_NO_LIBRARIES = "No libraries to load"; - public static final String ERROR_REPO_PROBE_FAILED = "repository probe failed with "; - public static final String ERROR_LIBRARY_FETCH_FAILED = "failed to retrieve "; - public static final String ERROR_FORCED_DOWNLOAD_FAILED = "Failed to download every file on a forced download"; - public static final String ERROR_INCOMPLETE_RETRIEVAL = "Not all libraries could be retrieved"; + public static final String ERROR_NO_LIBRARIES = "No libraries declared"; + public static final String ERROR_REPO_PROBE_FAILED = "Repository probe failed with "; + public static final String ERROR_LIBRARY_FETCH_FAILED = "Failed to retrieve "; + public static final String ERROR_INCOMPLETE_RETRIEVAL = "Missing Libraries :"; + public static final String MSG_NO_RETRIEVE = "Connections disabled"; + public static final String MSG_NO_LIBRARIES_TO_FETCH = "No libraries marked for retrieval"; + + + /** + * Init the task + * + * @throws org.apache.tools.ant.BuildException + * if something goes wrong with the build + */ + public void init() throws BuildException { + super.init(); + //set our default polocy + add(new AbsentFilesPolicy()); + } /** * add a repository. Only one is (currently) supported @@ -115,6 +139,64 @@ add(r); } + /** + * add anything that implements the library policy interface + * @param policy + */ + public void add(LibraryPolicy policy) { + policies.add(policy); + } + + /** + * add a schedule + * @param update + */ + public void addSchedule(ScheduledUpdatePolicy update) { + add(update); + } + + /** + * Declare that the update should be forced: everything + * must be fetched; it will be a failure if any are not + * @param policy + */ + public void addForce(ForceUpdatePolicy policy) { + add(policy); + } + + /** + * Declare that no files should be fetched + * @param policy + */ + public void addNoupdate(NoUpdatePolicy policy) { + add(policy); + } + + /** + * declare that the update should be timestamp driven + * @param policy + */ + public void addTimestamp(TimestampPolicy policy) { + add(policy); + } + + /** + * declare that only absent files are to be fetched + * @param policy + */ + public void addAbsentfiles(AbsentFilesPolicy policy) { + add(policy); + } + + + /** + * make a declaration about the number of files to fetch + * + * @param policy + */ + public void addAssertDownloaded(AssertDownloaded policy) { + add(policy); + } /** * add a library for retrieval @@ -134,14 +216,6 @@ this.destDir = destDir; } - /** - * flag to force a download even if the clock indicates it aint needed. - * - * @param forceDownload - */ - public void setForceDownload(boolean forceDownload) { - this.forceDownload = forceDownload; - } /** * test for being offline @@ -172,13 +246,6 @@ return destDir; } - /** - * get force download flag - * @return - */ - public boolean isForceDownload() { - return forceDownload; - } /** * get the list of libraries @@ -214,12 +281,38 @@ } /** + * get the current timestamp flag + * @return + */ + public boolean isUseTimestamp() { + return useTimestamp; + } + + /** + * set the timestamp flag. Not for export into XML + * @param useTimestamp + */ + public void _setUseTimestamp(boolean useTimestamp) { + this.useTimestamp = useTimestamp; + } + + /** + * get the current policy list + * @return + */ + public List getPolicies() { + return policies; + } + + /** * validate ourselves * * @throws BuildException */ public void validate() { - if (destDir == null || !destDir.isDirectory()) { + if (destDir == null + // || !destDir.isDirectory() + ) { throw new BuildException(ERROR_NO_DEST_DIR); } if (repository == null) { @@ -231,7 +324,6 @@ library.validate(); } } - /** * Called by the project to let the task do its work. * @@ -240,25 +332,90 @@ */ public void execute() throws BuildException { validate(); + if (isOffline()) { + log("No retrieval, task is \"offline\""); + } else { + doExecute(); + } + //validate the state + verifyAllLibrariesPresent(); + + //create the path + if (pathid != null) { + createPath(); + } + } + /** + * This is the real worker method + * + * @throws org.apache.tools.ant.BuildException + * if something goes wrong with the build + */ + private void doExecute() throws BuildException { destDir.mkdirs(); Repository repo = repository.resolve(); repo.validate(); if (libraries.size() == 0) { throw new BuildException(ERROR_NO_LIBRARIES); } - int failures = 0; log("Getting libraries from " + repo.toString(), Project.MSG_VERBOSE); log("Saving libraries to " + destDir.toString(), Project.MSG_VERBOSE); + //map libraries to files bindAllLibraries(); - if (isOffline()) { - log("No retrieval, task is \"offline\""); - //when offline, we just make sure everything is in place - verifyAllLibrariesPresent(); - return; + + + //flag to indicate whether the download should go ahead + boolean retrieve = true; + List processedPolicies = new ArrayList(policies.size()); + //iterate through all policies and execute their preload task + Iterator policyIterator = policies.enabledIterator(); + while (retrieve && policyIterator.hasNext()) { + LibraryPolicy libraryPolicy = (LibraryPolicy) policyIterator.next(); + retrieve=libraryPolicy.beforeConnect(this, libraryIterator()); + if(retrieve) { + //add all processed properties to the list, 'cept for anything that + //broke the chain + processedPolicies.add(libraryPolicy); + } else { + log("Policy "+libraryPolicy.getClass().getName() + + " disabled retrieval", + Project.MSG_VERBOSE); + } + } + + //see if we need to do a download + if(!retrieve) { + //if not, log it + log(MSG_NO_RETRIEVE); + } else { + int downloads = calculateFetchCount(); + if(downloads>0) { + //get the files + connectAndRetrieve(repo, useTimestamp); + } else { + //nothing to fetch + log(MSG_NO_LIBRARIES_TO_FETCH,Project.MSG_VERBOSE); + } + } + + //now reverse iterate through all processed properties. + for(int i=processedPolicies.size()-1;i>=0;i--) { + LibraryPolicy libraryPolicy = (LibraryPolicy)processedPolicies.get(i); + //and call their post-processor + libraryPolicy.afterFetched(this,libraryIterator() ); } + } + /** + * connect to the remote system, retrieve files + * @param repo + * @param useTimestamp + * @return number of failed retrievals. + */ + private int connectAndRetrieve(Repository repo, boolean useTimestamp) { //connect the repository + int failures = 0; repo.connect(this); try { @@ -274,82 +431,136 @@ Project.MSG_VERBOSE); reachable = false; } - if (!reachable) { - if (forceDownload) { - throw new BuildException(repo.toString() - + " is unreachable and forceDownload is set"); - } - } else { - log("Repository is live", Project.MSG_DEBUG); + if(!reachable) { + log("repository is not reachable", Project.MSG_INFO); + return 0; } - //iterate through the libs we have - Iterator it = filteredIterator(); + //iterate through the libs we have enabled + Iterator it = enabledLibrariesIterator(); while (it.hasNext()) { Library library = (Library) it.next(); - try { - //fetch it - if (repo.fetch(library)) { + //check to see if it is for fetching + if(library.isToFetch()) { + log("Fetching "+library.getNormalFilename(), Project.MSG_VERBOSE); + try { + //fetch it + boolean fetched=repo.fetch(library, useTimestamp) ; + //record the fact in the library + log("success; marking as fetched", + Project.MSG_DEBUG); + library._setFetched(fetched); + } catch (IOException e) { + log(ERROR_LIBRARY_FETCH_FAILED + library); + log(e.getMessage()); + //add failures + failures++; } - } catch (IOException e) { - //failures to fetch are logged at verbose level - log(ERROR_LIBRARY_FETCH_FAILED + library); - log(e.getMessage(), Project.MSG_VERBOSE); - //add failures - failures++; + } else { + //no fetch + log("Skipping " + library.getNormalFilename(), Project.MSG_VERBOSE); } } } finally { + + log("disconnecting",Project.MSG_VERBOSE); repo.disconnect(); } + return failures; + } - //at this point downloads have finished. - //we do still need to verify that everything worked. - if ((failures>0 && forceDownload)) { - throw new BuildException(ERROR_FORCED_DOWNLOAD_FAILED); + /** + * bind all libraries to our destination + */ + public void bindAllLibraries() { + Iterator it = libraries.iterator(); + while (it.hasNext()) { + Library library = (Library) it.next(); + library.bind(destDir); } + } - //validate the download - verifyAllLibrariesPresent(); - - //create the path - if(pathid!=null) { - createPath(); + /** + * set/clear the fetch flag on all libraries. + * @param fetch + */ + public void markAllLibrariesForFetch(boolean fetch) { + Iterator it = libraryIterator(); + while (it.hasNext()) { + Library library = (Library) it.next(); + library._setToFetch(fetch); } + } + /** + * set the fetch flag on all libraries that are absent; clear + * it from all those that exist + * + */ + public void markMissingLibrariesForFetch() { + Iterator it = libraryIterator(); + while (it.hasNext()) { + Library library = (Library) it.next(); + library._setToFetch(!library.exists()); + } } /** - * bind all libraries to our destination + * work out how many libraries to fetch + * @return count of enabled libraries with the to fetch bit set */ - protected void bindAllLibraries() { - Iterator it = libraries.iterator(); + public int calculateFetchCount() { + int count=0; + Iterator it = enabledLibrariesIterator(); while (it.hasNext()) { Library library = (Library) it.next(); - library.bind(destDir); + if(library.isToFetch()) { + count++; + }; + } + return count; + } + + /** + * work out how many libraries were fetched + * @return number of libraries that are enabled with the + * [EMAIL PROTECTED] Library#wasFetched()} flag true. + */ + public int calculateDownloadedCount() { + int count = 0; + //here verify that everything came in + Iterator downloaded = enabledLibrariesIterator(); + while (downloaded.hasNext()) { + Library library = (Library) downloaded.next(); + if (library.wasFetched()) { + count++; + } } + return count; } + /** * verify that all libraries are present */ protected void verifyAllLibrariesPresent() { //iterate through the libs we have boolean missing = false; - - Iterator it = filteredIterator(); + StringBuffer buffer=new StringBuffer(); + Iterator it = enabledLibrariesIterator(); while (it.hasNext()) { Library library = (Library) it.next(); //check for the library existing if (!library.exists()) { //and log if one is missing + buffer.append(library.toString()+"; "); log("Missing: " + library.toString(), Project.MSG_ERR); missing = true; } } if (missing) { - throw new BuildException(ERROR_INCOMPLETE_RETRIEVAL); + throw new BuildException(ERROR_INCOMPLETE_RETRIEVAL+buffer); } } @@ -358,7 +569,7 @@ */ private void createPath() { Path path = new Path(getProject()); - for (Iterator iterator = filteredIterator(); + for (Iterator iterator = enabledLibrariesIterator(); iterator.hasNext();) { ((Library) iterator.next()).appendToPath(path); } @@ -369,66 +580,17 @@ * get a filtered iterator of the dependencies * @return a new iterator that ignores disabled libraries */ - protected Iterator filteredIterator() { - return new LibraryIterator(libraries,getProject()); + public Iterator enabledLibrariesIterator() { + return libraries.enabledIterator(); } /** - * iterator through a list that skips everything that - * is not enabled + * get a list iterator for the files + * This gives you more power + * @return */ - private static class LibraryIterator implements Iterator { - private Iterator _underlyingIterator; - private Library _next; - private Project _project; - - - /** - * constructor - * @param collection - * @param project - */ - LibraryIterator(Collection collection, Project project) { - _project = project; - _underlyingIterator = collection.iterator(); - } - - - /** - * test for having another enabled component - * @return - */ - public boolean hasNext() { - while (_next == null && _underlyingIterator.hasNext()) { - Library candidate = (Library) _underlyingIterator.next(); - if (candidate.isEnabled(_project)) { - _next = candidate; - } - } - return (_next != null); - } - - /** - * get the next element - * @return - */ - public Object next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - Library result = _next; - _next = null; - return result; - } - - /** - * removal is not supported - * @throws UnsupportedOperationException always - */ - public void remove() { - throw new UnsupportedOperationException(); - } + public ListIterator libraryIterator() { + return libraries.listIterator(); } - } 1.4 +104 -12 ant/src/etc/testcases/taskdefs/optional/getlibraries.xml Index: getlibraries.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/optional/getlibraries.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- getlibraries.xml 2 Nov 2004 23:37:21 -0000 1.3 +++ getlibraries.xml 18 Nov 2004 16:00:18 -0000 1.4 @@ -7,8 +7,10 @@ <target name="init"> <property name="lib.dir" value="getlib"/> - <mkdir dir="${lib.dir}"/> - <property name="commons.logging" value="commons-logging-1.0.1.jar"/> + + <property name="commons.logging.project" value="commons-logging"/> + <property name="commons.logging" + value="${commons.logging.project}/jars/${commons.logging.project}-1.0.1.jar"/> <presetdef name="gl1"> <getlibraries destDir="${lib.dir}"> @@ -24,10 +26,11 @@ <macrodef name="assert-downloaded"> <attribute name="library" default="${commons.logging}"/> <sequential> + <property name="@{library}.path" location="${lib.dir}/@{library}" /> <available property="@{library}.exists" - file="${lib.dir}/@{library}"/> + file="[EMAIL PROTECTED]"/> <fail unless="@{library}.exists"> - Not found: [EMAIL PROTECTED] + Not found: [EMAIL PROTECTED] </fail> </sequential> </macrodef> @@ -35,20 +38,23 @@ <macrodef name="assert-not-downloaded"> <attribute name="library" default="${commons.logging}"/> <sequential> + <property name="@{library}.path" location="${lib.dir}/@{library}" /> <available property="@{library}.exists" - file="${lib.dir}/@{library}"/> + file="[EMAIL PROTECTED]"/> <fail if="@{library}.exists"> - Found: [EMAIL PROTECTED] + Found: [EMAIL PROTECTED] </fail> </sequential> </macrodef> </target> - <target name="cleanup"> + <target name="cleanup" depends="init"> <delete dir="${lib.dir}"/> </target> + <target name="teardown" depends="cleanup"/> + <target name="testEmpty" depends="init"> <getlibraries/> </target> @@ -99,7 +105,7 @@ <target name="testMavenInlineBadURL" depends="init"> <getlib> - + <mavenrepository url="http://invalid.example.org"/> </getlib> </target> @@ -118,19 +124,19 @@ <target name="testOverwrite" depends="init"> <getlib> <mavenrepository/> + <assertdownloaded count="1" /> </getlib> - <assert-downloaded/> <getlib> <mavenrepository/> + <assertdownloaded count="0" /> </getlib> </target> <target name="testIf" depends="init"> - <property name="trueProp" value="true" /> <gl1> <mavenrepository/> <library archive="commons-logging" project="commons-logging" version="1.0.1" - if="trueProp"/> + enabled="true"/> </gl1> <assert-downloaded/> </target> @@ -139,7 +145,7 @@ <gl1> <mavenrepository/> <library archive="commons-logging" project="commons-logging" version="1.0.1" - if="undefinedProp"/> + enabled="false"/> </gl1> <assert-not-downloaded/> </target> @@ -164,5 +170,91 @@ </getlib> <assert-downloaded/> </target> + + <target name="testSchedule" depends="init"> + <getlib > + <mavenrepository/> + <schedule days="1" markerFile="${lib.dir}/marker.txt"/> + <assertdownloaded count="1" /> + </getlib> + <getlib > + <mavenrepository/> + <schedule days="1" markerFile="${lib.dir}/marker.txt"/> + <assertdownloaded count="0" /> + </getlib> + </target> + + <target name="testForceEnabled" depends="init"> + <getlib> + <mavenrepository/> + <force enabled="true" /> + <assertdownloaded count="1" /> + </getlib> + <getlib> + <mavenrepository/> + <force enabled="true" /> + <assertdownloaded count="1" /> + </getlib> + </target> + + <target name="testForceDisabled" depends="init"> + <getlib> + <mavenrepository/> + <force enabled="true" /> + <assertdownloaded count="1" /> + </getlib> + <getlib > + <mavenrepository/> + <force enabled="false" /> + <assertdownloaded count="0" /> + </getlib> + </target> + + <target name="testAbsentFiles" depends="init"> + <getlib > + <mavenrepository/> + <absentfiles enabled="true" /> + <assertdownloaded count="1" /> + </getlib> + </target> + + <target name="testAbsentFilesTwice" depends="testAbsentFiles"> + <getlib > + <mavenrepository/> + <absentfiles enabled="true" /> + <assertdownloaded count="0" /> + </getlib> + </target> + + <target name="testNoUpdate" depends="init"> + <getlib > + <mavenrepository/> + <force /> + <noupdate /> + <assertdownloaded count="0" /> + </getlib> + </target> + + <target name="testTimestamp" depends="testAbsentFiles"> + <getlib > + <mavenrepository/> + <timestamp /> + <assertdownloaded count="0" /> + </getlib> + </target> + + <target name="testAssertDownloadedCountSet" depends="init"> + <getlib> + <mavenrepository/> + <assertdownloaded /> + </getlib> + </target> + + <target name="testAssertDownloadedCountTested" depends="init"> + <getlib> + <mavenrepository/> + <assertdownloaded count="152" /> + </getlib> + </target> </project> 1.5 +63 -4 ant/src/testcases/org/apache/tools/ant/taskdefs/optional/repository/GetLibrariesTest.java Index: GetLibrariesTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/optional/repository/GetLibrariesTest.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- GetLibrariesTest.java 2 Nov 2004 23:37:21 -0000 1.4 +++ GetLibrariesTest.java 18 Nov 2004 16:00:18 -0000 1.5 @@ -17,6 +17,7 @@ package org.apache.tools.ant.taskdefs.optional.repository; import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.taskdefs.repository.AssertDownloaded; /** * test the test libraries stuff. @@ -75,6 +76,10 @@ execIfOnline(targetName); } + /** + * exec a target, but only if we are online + * @param targetName + */ private void execIfOnline(String targetName) { if (offline()) { return; @@ -83,15 +88,28 @@ } public void testTwoRepositories() { - expectBuildException("testTwoRepositories", GetLibraries.ERROR_ONE_REPOSITORY_ONLY); + expectBuildException("testTwoRepositories", + GetLibraries.ERROR_ONE_REPOSITORY_ONLY); } public void testMavenInlineBadURL() { + expectExceptionIfOnline("testMavenInlineBadURL", + "testMavenInlineBadURL", + GetLibraries.ERROR_INCOMPLETE_RETRIEVAL); + } + + /** + * exec a target if we are online; expect an eception + * @param target + * @param cause caue of the faule + * @param message + */ + private void expectExceptionIfOnline(String target, String cause,String message) { if (offline()) { return; } - expectBuildException("testTwoRepositories", - GetLibraries.ERROR_INCOMPLETE_RETRIEVAL); + expectBuildExceptionContaining(target,cause, + message); } public void testRenaming() { @@ -119,4 +137,45 @@ execIfOnline("testSecurity"); } - } + public void testSchedule() { + execIfOnline("testSchedule"); + } + + public void testForceEnabled() { + execIfOnline("testForceEnabled"); + } + + public void testForceDisabled() { + execIfOnline("testForceDisabled"); + } + + public void testAbsentFiles() { + execIfOnline("testAbsentFiles"); + } + + public void testAbsentFilesTwice() { + execIfOnline("testAbsentFilesTwice"); + } + + public void testNoUpdate() { + expectExceptionIfOnline("testNoUpdate", + "update disabled; dest file missing", + GetLibraries.ERROR_INCOMPLETE_RETRIEVAL); + } + + public void testTimestamp() { + execIfOnline("testTimestamp"); + } + + public void testAssertDownloadedCountSet() { + expectExceptionIfOnline("testAssertDownloadedCountSet", + "No count in assertdownloaded", + AssertDownloaded.ERROR_NO_COUNT); + } + + public void testAssertDownloadedCountTested() { + expectExceptionIfOnline("testAssertDownloadedCountTested", + "Wrong count in assertdownloaded", + AssertDownloaded.ERROR_DOWNLOAD_FAILURE); + } +} 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElement.java Index: EnabledLibraryElement.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; /** * This is for any element that is enabled */ public interface EnabledLibraryElement { /** * turn element on/off * @param enabled */ void setEnabled(boolean enabled); /** * get the current enablement flag * @return */ boolean getEnabled(); } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/ScheduledUpdatePolicy.java Index: ScheduledUpdatePolicy.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import org.apache.tools.ant.taskdefs.optional.repository.Library; import org.apache.tools.ant.taskdefs.optional.repository.Repository; import org.apache.tools.ant.util.FileUtils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Iterator; import java.util.ListIterator; import java.util.Properties; /** * This [EMAIL PROTECTED] org.apache.tools.ant.taskdefs.repository.LibraryPolicy} updates the files only when the schedule * indicates that it should. * <p/> * The default interval is eleven hours; it's prime, it encourages * regular but not excessive days. * <p/> * It requires a marker file which is used to save a list of all files * that were saved. If anything in the list of files changes then the * update is triggered again. */ public class ScheduledUpdatePolicy extends BaseLibraryPolicy { private File markerFile; private int hours=17; private int days=0; /** * if not null, this means that we have a marker file to save */ private Properties markerFileToSave; public static final String ERROR_NO_MARKER_FILE = "No marker file"; public static final String MARKER_MISMATCH = "No match between last update and current one"; public static final String INTERVAL_TRIGGERS_UPDATE = "Interval between updates is long; updating"; public static final String INTERVAL_SHORT_NO_UPDATE = "Interval between updates is short; no update"; public File getMarkerFile() { return markerFile; } /** * set a file that stores the history of the operation * @param markerFile */ public void setMarkerFile(File markerFile) { this.markerFile = markerFile; } public int getHours() { return hours; } /** * set the interval between updates in hours * @param hours */ public void setHours(int hours) { this.hours = hours; } public int getDays() { return days; } /** * set the interval between updates in days. * @param days */ public void setDays(int days) { this.days = days; } /** * get the refresh interval in milliseconds * @return */ public long getInterval() { return ((days*24)+hours)*60*60000; } /** * Method called before we connect * * @param owner * * @param libraries * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries) { Repository repository=owner.getRepository(); if(markerFile==null) { throw new BuildException(ERROR_NO_MARKER_FILE); } Properties now = makeProperties(owner.enabledLibrariesIterator(), repository); try { if(markerFile.exists()) { long timestamp=markerFile.lastModified(); Properties then=loadMarkerFile(); long currentTime=System.currentTimeMillis(); long diff=currentTime-timestamp; if(now.equals(then)) { if(diff<getInterval()) { owner.log(INTERVAL_SHORT_NO_UPDATE, Project.MSG_VERBOSE); return false; } else { owner.log(INTERVAL_TRIGGERS_UPDATE, Project.MSG_VERBOSE); return true; } } else { owner.log(MARKER_MISMATCH, Project.MSG_VERBOSE); } } else { owner.log("Marker file not found", Project.MSG_VERBOSE); } markerFileToSave = now; return true; } catch (IOException e) { throw new BuildException("Marker file "+markerFile.getAbsolutePath()+" access failed",e); } } /** * method called after a (nominally successful fetch) * * @param owner * @param libraries */ public void afterFetched(GetLibraries owner, ListIterator libraries) { if(markerFileToSave!=null) { //if we get here, we need to save the file try { saveMarkerFile(markerFileToSave); } catch (IOException e) { throw new BuildException("Failed to save marker file " +markerFile, e); } } else { //touch the file anyway markerFile.setLastModified(System.currentTimeMillis()); } } /** * make a properties file from the library list * @param libraries iterator of type Library. * @return a new properties file */ protected Properties makeProperties(Iterator libraries, Repository repository) { Properties props=new Properties(); int counter=1; while (libraries.hasNext()) { Library library = (Library) libraries.next(); String name=makeEntry(library); props.put(Integer.toString(counter),name); } props.put("repository",repository.getRepositoryURI()); return props; } /** * save a property file to disk. * @param props * @throws IOException */ protected void saveMarkerFile(Properties props) throws IOException { markerFile.getParentFile().mkdirs(); OutputStream out= new BufferedOutputStream(new FileOutputStream(markerFile)); try { props.store(out,null); } finally { FileUtils.close(out); } } /** * Load an input stream * @return * @throws IOException */ protected Properties loadMarkerFile() throws IOException { Properties props=new Properties(); InputStream in=new BufferedInputStream(new FileInputStream(markerFile)); try { props.load(in); return props; } finally { FileUtils.close(in); } } /** * make an entry for the properties file * @param lib * @return */ protected String makeEntry(Library lib) { return lib.getMavenPath('/')+"//"+lib.getNormalFilename(); } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElementList.java Index: EnabledLibraryElementList.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.NoSuchElementException; /** * List with an enablement iterator. */ public class EnabledLibraryElementList extends LinkedList { /** * Constructs an empty list. */ public EnabledLibraryElementList() { } /** * return an iterator that only iterates over enabled stuff * @return */ public Iterator enabledIterator() { return new EnabledIterator(this); } /** * iterator through a list that skips everything that is not enabled */ private static class EnabledIterator implements Iterator { private Iterator _underlyingIterator; private EnabledLibraryElement _next; /** * constructor * * @param collection */ EnabledIterator(Collection collection) { _underlyingIterator = collection.iterator(); } /** * test for having another enabled component * * @return */ public boolean hasNext() { while (_next == null && _underlyingIterator.hasNext()) { EnabledLibraryElement candidate = (EnabledLibraryElement) _underlyingIterator.next(); if (candidate.getEnabled()) { _next = candidate; } } return (_next != null); } /** * get the next element * * @return */ public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } EnabledLibraryElement result = _next; _next = null; return result; } /** * removal is not supported * * @throws UnsupportedOperationException always */ public void remove() { throw new UnsupportedOperationException(); } } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/AbsentFilesPolicy.java Index: AbsentFilesPolicy.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import java.util.ListIterator; /** * This policy only marks absent(enabled) files. */ public class AbsentFilesPolicy extends BaseLibraryPolicy { /** * Tell owner to mark all missing libraries as fetchable * * @param owner * @param libraries * * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries) { owner.markMissingLibrariesForFetch(); return true; } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/TimestampPolicy.java Index: TimestampPolicy.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import java.util.ListIterator; /** * Mark all files for fetching, but timestamp driven * This will only update changed files. Unlike [EMAIL PROTECTED] ForceUpdatePolicy}, * there is no post-download verification that everything got fetched */ public class TimestampPolicy extends BaseLibraryPolicy { /** * Method called before we connect. Caller can manipulate the list, * * @param owner * @param libraries * * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries) { owner.markAllLibrariesForFetch(true); owner._setUseTimestamp(true); return true; } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/BaseLibraryPolicy.java Index: BaseLibraryPolicy.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import java.util.ListIterator; /** */ public abstract class BaseLibraryPolicy implements LibraryPolicy { /** * enabled flag */ private boolean enabled=true; /** * turn policy on/off * * @param enabled */ public void setEnabled(boolean enabled) { this.enabled = enabled; } /** * are we enabled * @return true if [EMAIL PROTECTED] #enabled} is set */ public boolean getEnabled() { return enabled; } /** * Method called before we connect. Caller can manipulate the list, * * @param owner * @param libraries * * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries) { return true; } /** * method called after a successful connection process. * * @param owner * @param libraries * * @throws org.apache.tools.ant.BuildException * */ public void afterFetched(GetLibraries owner, ListIterator libraries) { } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/LibraryPolicy.java Index: LibraryPolicy.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import java.util.ListIterator; /** * An interface that things can support to change the library behaviour. * Example uses could be: extra validation (signatures, etc), filename remapping * * * Here is the use * <ol> * <li>Policies are executed in order of declaration. * <li>The [EMAIL PROTECTED] #beforeConnect(org.apache.tools.ant.taskdefs.optional.repository.GetLibraries, java.util.ListIterator)} call, * is called before any connection has been initiated; policies can manipulate * the library list, set/reset their toFetch list, rename destination files, etc. * <li>If any policy returns false from the method, the connection does not proceed. * This is not an error, provided the files are actually present. * <li>After running through the fetch of all files marked for download, * every policy implementation will again be called in order of declaration. * <li>The [EMAIL PROTECTED] #afterFetched(org.apache.tools.ant.taskdefs.optional.repository.GetLibraries, java.util.ListIterator)} method * does not return anything. * <li>Either method can throw a BuildException to indicate some kind of error. * </ol> * */ public interface LibraryPolicy extends EnabledLibraryElement { /** * Method called before we connect. Caller can manipulate the list, * * * @param owner * * @param libraries * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries); /** * method called after a successful connection process. * @param owner * @param libraries * @throws org.apache.tools.ant.BuildException */ public void afterFetched(GetLibraries owner,ListIterator libraries); } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/ForceUpdatePolicy.java Index: ForceUpdatePolicy.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import org.apache.tools.ant.taskdefs.optional.repository.Library; import java.util.Iterator; import java.util.ListIterator; /** * This update policy marks all libraries for download. * After downloading, it will raise an error if any one of the files was not * retrieved. */ public class ForceUpdatePolicy extends BaseLibraryPolicy { public static final String ERROR_FORCED_DOWNLOAD_FAILED = "Failed to download file:"; public String getName() { return "force"; } /** * * @param owner * @param libraries * * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries) { owner.markAllLibrariesForFetch(true); owner._setUseTimestamp(false); return true; } /** * method called after a successful connection process. * * @param owner * @param libraries * * @throws org.apache.tools.ant.BuildException * */ public void afterFetched(GetLibraries owner, ListIterator libraries) { //here verify that everything came in Iterator downloaded = owner.enabledLibrariesIterator(); while (downloaded.hasNext()) { Library library = (Library) downloaded.next(); if (library.isToFetch() && !library.wasFetched()) { throw new BuildException(ERROR_FORCED_DOWNLOAD_FAILED + library.getDestFilename()); } } } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/NoUpdatePolicy.java Index: NoUpdatePolicy.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import java.util.ListIterator; /** * Reset the fetch bit on all libraries */ public class NoUpdatePolicy extends BaseLibraryPolicy { /** * Method called before we connect. Caller can manipulate the list, * * @param owner * @param libraries * * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries) { // mark all files as no Fetch owner.markAllLibrariesForFetch(false); return true; } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/repository/AssertDownloaded.java Index: AssertDownloaded.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.repository; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries; import java.util.ListIterator; /** * This policy is really there for testing the tasks, but you can use * it for debugging your own logic. */ public class AssertDownloaded extends BaseLibraryPolicy { /** * our count of files to fetch; null means undefined */ Integer count; public static final String ERROR_NO_COUNT = "No count declared"; public static final String ERROR_DOWNLOAD_FAILURE = "Download count mismatch: expected "; /** * set the number of files that must be fetched. * It is an error if the count does not match. * @param count */ public void setCount(Integer count) { this.count = count; } /** * Method called before we connect. Caller can manipulate the list, * * @param owner * @param libraries * * @return true if the connection is to go ahead * * @throws org.apache.tools.ant.BuildException * if needed */ public boolean beforeConnect(GetLibraries owner, ListIterator libraries) { if(count==null) { throw new BuildException(ERROR_NO_COUNT); } return true; } /** * method called after a successful connection process. * * @param owner * @param libraries * * @throws org.apache.tools.ant.BuildException * */ public void afterFetched(GetLibraries owner, ListIterator libraries) { int fetched=owner.calculateDownloadedCount(); if(fetched!=count.intValue()) { throw new BuildException(ERROR_DOWNLOAD_FAILURE +count +" but fetched "+fetched); } } } 1.45 +6 -5 ant/src/main/org/apache/tools/ant/taskdefs/Get.java Index: Get.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Get.java,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- Get.java 2 Nov 2004 23:37:21 -0000 1.44 +++ Get.java 18 Nov 2004 16:00:18 -0000 1.45 @@ -17,6 +17,11 @@ package org.apache.tools.ant.taskdefs; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.FileUtils; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -26,11 +31,6 @@ import java.net.URL; import java.net.URLConnection; import java.util.Date; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.util.FileUtils; -import org.apache.tools.ant.util.JavaEnvUtils; /** * Gets a particular file from a URL source. @@ -115,6 +115,7 @@ progress = new NullProgress(); } log("Getting: " + source, logLevel); + log("To: " + dest.getAbsolutePath(), logLevel); //set the timestamp to the file date. long timestamp = 0;
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]