From f630ef56ed68316b07aaa27e05cf871de1070498 Mon Sep 17 00:00:00 2001 From: Steve Loughran Date: Thu, 18 Nov 2004 16:00:18 +0000 Subject: [PATCH] Updated code, plus new classes. After this checkin I'm about to move and rename some of the existing stuff. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277053 13f79535-47bb-0310-9956-ffa450edef68 --- .../taskdefs/optional/getlibraries.xml | 116 ++++- .../org/apache/tools/ant/taskdefs/Get.java | 11 +- .../optional/repository/GetLibraries.java | 424 ++++++++++++------ .../optional/repository/HttpRepository.java | 83 +--- .../taskdefs/optional/repository/Library.java | 178 +++++--- .../optional/repository/MavenRepository.java | 20 +- .../optional/repository/Repository.java | 11 +- .../optional/repository/RepositoryRef.java | 12 +- .../repository/AbsentFilesPolicy.java | 43 ++ .../taskdefs/repository/AssertDownloaded.java | 82 ++++ .../repository/BaseLibraryPolicy.java | 76 ++++ .../repository/EnabledLibraryElement.java | 34 ++ .../repository/EnabledLibraryElementList.java | 100 +++++ .../repository/ForceUpdatePolicy.java | 76 ++++ .../taskdefs/repository/LibraryPolicy.java | 71 +++ .../taskdefs/repository/NoUpdatePolicy.java | 44 ++ .../repository/ScheduledUpdatePolicy.java | 242 ++++++++++ .../taskdefs/repository/TimestampPolicy.java | 47 ++ .../optional/repository/GetLibrariesTest.java | 67 ++- 19 files changed, 1460 insertions(+), 277 deletions(-) create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/AbsentFilesPolicy.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/AssertDownloaded.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/BaseLibraryPolicy.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElement.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElementList.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/ForceUpdatePolicy.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/LibraryPolicy.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/NoUpdatePolicy.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/ScheduledUpdatePolicy.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/repository/TimestampPolicy.java diff --git a/src/etc/testcases/taskdefs/optional/getlibraries.xml b/src/etc/testcases/taskdefs/optional/getlibraries.xml index 105db852f..0e242be02 100644 --- a/src/etc/testcases/taskdefs/optional/getlibraries.xml +++ b/src/etc/testcases/taskdefs/optional/getlibraries.xml @@ -7,8 +7,10 @@ - - + + + @@ -24,10 +26,11 @@ + + file="${@{library}.path}"/> - Not found: ${lib.dir}@{library} + Not found: ${@{library}.path} @@ -35,20 +38,23 @@ + + file="${@{library}.path}"/> - Found: ${lib.dir}@{library} + Found: ${@{library}.path} - + + + @@ -99,7 +105,7 @@ - + @@ -118,19 +124,19 @@ + - + - + enabled="true"/> @@ -139,7 +145,7 @@ + enabled="false"/> @@ -164,5 +170,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/Get.java b/src/main/org/apache/tools/ant/taskdefs/Get.java index 1ac4dc4f6..8e4a356b6 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Get.java +++ b/src/main/org/apache/tools/ant/taskdefs/Get.java @@ -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.HttpURLConnection; 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 @@ public class Get extends Task { progress = new NullProgress(); } log("Getting: " + source, logLevel); + log("To: " + dest.getAbsolutePath(), logLevel); //set the timestamp to the file date. long timestamp = 0; diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/repository/GetLibraries.java b/src/main/org/apache/tools/ant/taskdefs/optional/repository/GetLibraries.java index 031b351cf..05a499303 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/repository/GetLibraries.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/repository/GetLibraries.java @@ -19,16 +19,23 @@ 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.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.
    @@ -39,18 +46,13 @@ import java.util.NoSuchElementException; * @ant.task * @since Ant 1.7 */ -public class GetLibraries extends Task { +public final class GetLibraries extends Task { /** * destination */ private File destDir; - /** - * flag to force a download - */ - private boolean forceDownload = false; - /** * flag to force offline */ @@ -59,7 +61,12 @@ public class GetLibraries extends Task { /** * 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 @@ public class GetLibraries extends Task { */ 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 @@ public class GetLibraries extends Task { 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 @@ public class GetLibraries extends Task { 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 @@ public class GetLibraries extends Task { return destDir; } - /** - * get force download flag - * @return - */ - public boolean isForceDownload() { - return forceDownload; - } /** * get the list of libraries @@ -213,13 +280,39 @@ public class GetLibraries extends Task { this.pathid = pathid; } + /** + * 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 @@ public class GetLibraries extends Task { library.validate(); } } - /** * Called by the project to let the task do its work. * @@ -240,25 +332,90 @@ public class GetLibraries extends Task { */ 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 @@ public class GetLibraries extends Task { 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 + * {@link 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 @@ public class GetLibraries extends Task { */ 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 @@ public class GetLibraries extends Task { * 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(); } - } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/repository/HttpRepository.java b/src/main/org/apache/tools/ant/taskdefs/optional/repository/HttpRepository.java index ac28c00e5..ca88acb26 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/repository/HttpRepository.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/repository/HttpRepository.java @@ -68,8 +68,6 @@ public abstract class HttpRepository extends Repository { * 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 @@ public abstract class HttpRepository extends Repository { 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 @@ public abstract class HttpRepository extends Repository { * * @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 @@ public abstract class HttpRepository extends Repository { 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 abstract class HttpRepository extends Repository { */ 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 @@ public abstract class HttpRepository extends Repository { 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 across instances. * - * @return the base URL + * @return */ - public String toString() { - return "Repository at " + getUrl(); + public String getRepositoryURI() { + return "HttpRepository://"+getUrl(); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/repository/Library.java b/src/main/org/apache/tools/ant/taskdefs/optional/repository/Library.java index da34ac033..30258431e 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/repository/Library.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/repository/Library.java @@ -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 @@ import java.io.File; * * @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 {@link #enabled} is set + */ + public boolean getEnabled() { + return enabled; + } //project "ant" private String project; @@ -52,14 +76,12 @@ public class Library { 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 @@ public class Library { * suffix */ private String suffix = "jar"; + public static final String ERROR_FILE_IS_A_DIR = "Library file is a directory:"; /** @@ -154,38 +177,6 @@ public class Library { this.suffix = suffix; } - /** - * 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) @@ -195,6 +186,14 @@ public class Library { return libraryFile; } + /** + * set the library file. + * @param libraryFile + */ + public void setLibraryFile(File libraryFile) { + this.libraryFile = libraryFile; + } + /** * fault if the field is null or empty * @@ -241,10 +240,16 @@ public class Library { */ 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 @@ public class Library { 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 @@ public class Library { 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 {@link #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; + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/repository/MavenRepository.java b/src/main/org/apache/tools/ant/taskdefs/optional/repository/MavenRepository.java index ea0ff1531..288152e3d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/repository/MavenRepository.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/repository/MavenRepository.java @@ -19,10 +19,9 @@ package org.apache.tools.ant.taskdefs.optional.repository; 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; @@ -90,18 +89,29 @@ public class MavenRepository extends HttpRepository { return "Maven Repository at " + getUrl(); } + /** + * this is a string that uniquely describes the repository and can be used + * for equality tests across 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 @@ public class MavenRepository extends HttpRepository { } } - -// e1b1720a761ca36eaa47e1c7d802e676 \ No newline at end of file diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/repository/Repository.java b/src/main/org/apache/tools/ant/taskdefs/optional/repository/Repository.java index edcf550f0..56b69b3a5 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/repository/Repository.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/repository/Repository.java @@ -99,11 +99,18 @@ public abstract class Repository extends DataType { /** * 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 across instances. + * @return + */ + public abstract String getRepositoryURI(); } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/repository/RepositoryRef.java b/src/main/org/apache/tools/ant/taskdefs/optional/repository/RepositoryRef.java index b1c4ef404..d2d750c33 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/repository/RepositoryRef.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/repository/RepositoryRef.java @@ -70,10 +70,20 @@ public final class RepositoryRef extends Repository { * * @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 across instances. + * + * @return + */ + public String getRepositoryURI() { + return "ref://"+getRefid(); + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/AbsentFilesPolicy.java b/src/main/org/apache/tools/ant/taskdefs/repository/AbsentFilesPolicy.java new file mode 100644 index 000000000..4a7c8b539 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/AbsentFilesPolicy.java @@ -0,0 +1,43 @@ +/* + * 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; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/AssertDownloaded.java b/src/main/org/apache/tools/ant/taskdefs/repository/AssertDownloaded.java new file mode 100644 index 000000000..9fe5bae25 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/AssertDownloaded.java @@ -0,0 +1,82 @@ +/* + * 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); + } + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/BaseLibraryPolicy.java b/src/main/org/apache/tools/ant/taskdefs/repository/BaseLibraryPolicy.java new file mode 100644 index 000000000..bb70dbb3e --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/BaseLibraryPolicy.java @@ -0,0 +1,76 @@ +/* + * 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 {@link #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) { + + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElement.java b/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElement.java new file mode 100644 index 000000000..1da661eeb --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElement.java @@ -0,0 +1,34 @@ +/* + * 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(); +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElementList.java b/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElementList.java new file mode 100644 index 000000000..ff5168018 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/EnabledLibraryElementList.java @@ -0,0 +1,100 @@ +/* + * 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(); + } + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/ForceUpdatePolicy.java b/src/main/org/apache/tools/ant/taskdefs/repository/ForceUpdatePolicy.java new file mode 100644 index 000000000..38d677f2b --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/ForceUpdatePolicy.java @@ -0,0 +1,76 @@ +/* +* 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()); + } + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/LibraryPolicy.java b/src/main/org/apache/tools/ant/taskdefs/repository/LibraryPolicy.java new file mode 100644 index 000000000..b0facedb1 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/LibraryPolicy.java @@ -0,0 +1,71 @@ +/* + * 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 + *
      + *
    1. Policies are executed in order of declaration. + *
    2. The {@link #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. + *
    3. If any policy returns false from the method, the connection does not proceed. + * This is not an error, provided the files are actually present. + *
    4. After running through the fetch of all files marked for download, + * every policy implementation will again be called in order of declaration. + *
    5. The {@link #afterFetched(org.apache.tools.ant.taskdefs.optional.repository.GetLibraries, java.util.ListIterator)} method + * does not return anything. + *
    6. Either method can throw a BuildException to indicate some kind of error. + *
    + * + */ +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); + + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/NoUpdatePolicy.java b/src/main/org/apache/tools/ant/taskdefs/repository/NoUpdatePolicy.java new file mode 100644 index 000000000..7c5d0adaf --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/NoUpdatePolicy.java @@ -0,0 +1,44 @@ +/* + * 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; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/repository/ScheduledUpdatePolicy.java b/src/main/org/apache/tools/ant/taskdefs/repository/ScheduledUpdatePolicy.java new file mode 100644 index 000000000..6fef41d5b --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/repository/ScheduledUpdatePolicy.java @@ -0,0 +1,242 @@ +/* + * 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 {@link org.apache.tools.ant.taskdefs.repository.LibraryPolicy} updates the files only when the schedule + * indicates that it should. + *

    + * The default interval is eleven hours; it's prime, it encourages + * regular but not excessive days. + *

    + * 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