conditional dependencies and setting of a path to the dependency list. Moving from httpclient to get is still todo. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276982 13f79535-47bb-0310-9956-ffa450edef68master
@@ -1,5 +1,5 @@ | |||||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||||
<project name="getlibraries" basedir="." default="all"> | |||||
<project name="getlibraries" basedir="." default="init"> | |||||
<!-- use the normal one at ibiblio--> | <!-- use the normal one at ibiblio--> | ||||
@@ -10,12 +10,17 @@ | |||||
<mkdir dir="${lib.dir}"/> | <mkdir dir="${lib.dir}"/> | ||||
<property name="commons.logging" value="commons-logging-1.0.1.jar"/> | <property name="commons.logging" value="commons-logging-1.0.1.jar"/> | ||||
<presetdef name="getlib"> | |||||
<presetdef name="gl1"> | |||||
<getlibraries destDir="${lib.dir}"> | <getlibraries destDir="${lib.dir}"> | ||||
<library archive="commons-logging" project="commons-logging" version="1.0.1"/> | |||||
</getlibraries> | </getlibraries> | ||||
</presetdef> | </presetdef> | ||||
<presetdef name="getlib"> | |||||
<gl1 destDir="${lib.dir}"> | |||||
<library archive="commons-logging" project="commons-logging" version="1.0.1"/> | |||||
</gl1> | |||||
</presetdef> | |||||
<macrodef name="assert-downloaded"> | <macrodef name="assert-downloaded"> | ||||
<attribute name="library" default="${commons.logging}"/> | <attribute name="library" default="${commons.logging}"/> | ||||
<sequential> | <sequential> | ||||
@@ -26,6 +31,18 @@ | |||||
</fail> | </fail> | ||||
</sequential> | </sequential> | ||||
</macrodef> | </macrodef> | ||||
<macrodef name="assert-not-downloaded"> | |||||
<attribute name="library" default="${commons.logging}"/> | |||||
<sequential> | |||||
<available property="@{library}.exists" | |||||
file="${lib.dir}/@{library}"/> | |||||
<fail if="@{library}.exists"> | |||||
Found: ${lib.dir}@{library} | |||||
</fail> | |||||
</sequential> | |||||
</macrodef> | |||||
</target> | </target> | ||||
<target name="cleanup"> | <target name="cleanup"> | ||||
@@ -108,5 +125,37 @@ | |||||
</getlib> | </getlib> | ||||
</target> | </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"/> | |||||
</gl1> | |||||
<assert-downloaded/> | |||||
</target> | |||||
<target name="testUnless" depends="init"> | |||||
<gl1> | |||||
<mavenrepository/> | |||||
<library archive="commons-logging" project="commons-logging" version="1.0.1" | |||||
if="undefinedProp"/> | |||||
</gl1> | |||||
<assert-not-downloaded/> | |||||
</target> | |||||
<target name="testPathID" depends="init"> | |||||
<getlib pathid="commons.logging"> | |||||
<mavenrepository/> | |||||
</getlib> | |||||
<available | |||||
property="logging.found" | |||||
classname="org.apache.commons.logging.Log" | |||||
classpathref="commons.logging" | |||||
ignoresystemclasses="true" /> | |||||
<fail unless="logging.found"> | |||||
Did not find commons logging in the path | |||||
</fail> | |||||
</target> | |||||
</project> | </project> | ||||
@@ -19,13 +19,16 @@ package org.apache.tools.ant.taskdefs.optional.repository; | |||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.types.Path; | |||||
import org.apache.tools.ant.types.Reference; | import org.apache.tools.ant.types.Reference; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.Collection; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.LinkedList; | import java.util.LinkedList; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.NoSuchElementException; | |||||
/** | /** | ||||
* This task will retrieve one or more libraries from a repository. <ol> | * This task will retrieve one or more libraries from a repository. <ol> | ||||
@@ -64,6 +67,13 @@ public class GetLibraries extends Task { | |||||
private Repository repository; | private Repository repository; | ||||
/** | |||||
* Optional. A name for a path to define from the dependencies specified. | |||||
*/ | |||||
private String pathid; | |||||
public static final String ERROR_ONE_REPOSITORY_ONLY = "Only one repository is allowed"; | 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_DEST_DIR = "No destination directory"; | ||||
public static final String ERROR_NO_REPOSITORY = "No repository defined"; | public static final String ERROR_NO_REPOSITORY = "No repository defined"; | ||||
@@ -167,18 +177,47 @@ public class GetLibraries extends Task { | |||||
return destDir; | return destDir; | ||||
} | } | ||||
/** | |||||
* get fore download flag | |||||
* @return | |||||
*/ | |||||
public boolean isForceDownload() { | public boolean isForceDownload() { | ||||
return forceDownload; | return forceDownload; | ||||
} | } | ||||
/** | |||||
* get the list of libraries | |||||
* @return | |||||
*/ | |||||
public List getLibraries() { | public List getLibraries() { | ||||
return libraries; | return libraries; | ||||
} | } | ||||
/** | |||||
* get our repository | |||||
* @return | |||||
*/ | |||||
public Repository getRepository() { | public Repository getRepository() { | ||||
return repository; | return repository; | ||||
} | } | ||||
/** | |||||
* get the pathID if defined | |||||
* @return | |||||
*/ | |||||
public String getPathid() { | |||||
return pathid; | |||||
} | |||||
/** | |||||
* the name of a path reference to be created referring | |||||
* to the libraries. | |||||
* @param pathid | |||||
*/ | |||||
public void setPathid(String pathid) { | |||||
this.pathid = pathid; | |||||
} | |||||
/** | /** | ||||
* validate ourselves | * validate ourselves | ||||
* | * | ||||
@@ -208,17 +247,17 @@ public class GetLibraries extends Task { | |||||
validate(); | validate(); | ||||
Repository repo = repository.resolve(); | Repository repo = repository.resolve(); | ||||
repo.validate(); | repo.validate(); | ||||
int toFetch = libraries.size(); | |||||
if (toFetch == 0) { | |||||
if (libraries.size() == 0) { | |||||
throw new BuildException(ERROR_NO_LIBRARIES); | throw new BuildException(ERROR_NO_LIBRARIES); | ||||
} | } | ||||
int fetched = 0; | |||||
int failures = 0; | |||||
log("Getting libraries from " + repo.toString(), Project.MSG_VERBOSE); | log("Getting libraries from " + repo.toString(), Project.MSG_VERBOSE); | ||||
log("Saving libraries to " + destDir.toString(), Project.MSG_VERBOSE); | log("Saving libraries to " + destDir.toString(), Project.MSG_VERBOSE); | ||||
bindAllLibraries(); | bindAllLibraries(); | ||||
if (isOffline()) { | if (isOffline()) { | ||||
log("No retrieval, task is \"offline\""); | log("No retrieval, task is \"offline\""); | ||||
//when offline, we just make sure everything is in place | |||||
verifyAllLibrariesPresent(); | verifyAllLibrariesPresent(); | ||||
return; | return; | ||||
} | } | ||||
@@ -250,18 +289,19 @@ public class GetLibraries extends Task { | |||||
} | } | ||||
//iterate through the libs we have | //iterate through the libs we have | ||||
Iterator it = libraries.iterator(); | |||||
Iterator it = filteredIterator(); | |||||
while (it.hasNext()) { | while (it.hasNext()) { | ||||
Library library = (Library) it.next(); | Library library = (Library) it.next(); | ||||
library.bind(destDir); | |||||
try { | try { | ||||
//fetch it | |||||
if (repo.fetch(library)) { | if (repo.fetch(library)) { | ||||
fetched++; | |||||
} | } | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
//failures to fetch are logged at verbose level | //failures to fetch are logged at verbose level | ||||
log(ERROR_LIBRARY_FETCH_FAILED + library); | log(ERROR_LIBRARY_FETCH_FAILED + library); | ||||
log(e.getMessage(), Project.MSG_VERBOSE); | log(e.getMessage(), Project.MSG_VERBOSE); | ||||
//add failures | |||||
failures++; | |||||
} | } | ||||
} | } | ||||
} finally { | } finally { | ||||
@@ -270,12 +310,18 @@ public class GetLibraries extends Task { | |||||
//at this point downloads have finished. | //at this point downloads have finished. | ||||
//we do still need to verify that everything worked. | //we do still need to verify that everything worked. | ||||
if ((fetched < toFetch && forceDownload)) { | |||||
if ((failures>0 && forceDownload)) { | |||||
throw new BuildException(ERROR_FORCED_DOWNLOAD_FAILED); | throw new BuildException(ERROR_FORCED_DOWNLOAD_FAILED); | ||||
} | } | ||||
//validate the download | |||||
verifyAllLibrariesPresent(); | verifyAllLibrariesPresent(); | ||||
//create the path | |||||
if(pathid!=null) { | |||||
createPath(); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -296,7 +342,7 @@ public class GetLibraries extends Task { | |||||
//iterate through the libs we have | //iterate through the libs we have | ||||
boolean missing = false; | boolean missing = false; | ||||
Iterator it = libraries.iterator(); | |||||
Iterator it = filteredIterator(); | |||||
while (it.hasNext()) { | while (it.hasNext()) { | ||||
Library library = (Library) it.next(); | Library library = (Library) it.next(); | ||||
//check for the library existing | //check for the library existing | ||||
@@ -312,4 +358,84 @@ public class GetLibraries extends Task { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* create a path; requires pathID!=null | |||||
*/ | |||||
private void createPath() { | |||||
Path path = new Path(getProject()); | |||||
for (Iterator iterator = filteredIterator(); | |||||
iterator.hasNext();) { | |||||
((Library) iterator.next()).appendToPath(path); | |||||
} | |||||
getProject().addReference(pathid, path); | |||||
} | |||||
/** | |||||
* get a filtered iterator of the dependencies | |||||
* @return a new iterator that ignores disabled libraries | |||||
*/ | |||||
protected Iterator filteredIterator() { | |||||
return new LibraryIterator(libraries,getProject()); | |||||
} | |||||
/** | |||||
* iterator through a list that skips everything that | |||||
* is not enabled | |||||
*/ | |||||
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(); | |||||
} | |||||
} | |||||
} | } |
@@ -16,7 +16,12 @@ | |||||
*/ | */ | ||||
package org.apache.tools.ant.taskdefs.optional.repository; | package org.apache.tools.ant.taskdefs.optional.repository; | ||||
import org.apache.commons.httpclient.*; | |||||
import org.apache.commons.httpclient.Credentials; | |||||
import org.apache.commons.httpclient.DefaultMethodRetryHandler; | |||||
import org.apache.commons.httpclient.HttpClient; | |||||
import org.apache.commons.httpclient.HttpMethod; | |||||
import org.apache.commons.httpclient.HttpStatus; | |||||
import org.apache.commons.httpclient.UsernamePasswordCredentials; | |||||
import org.apache.commons.httpclient.cookie.CookiePolicy; | import org.apache.commons.httpclient.cookie.CookiePolicy; | ||||
import org.apache.commons.httpclient.methods.GetMethod; | import org.apache.commons.httpclient.methods.GetMethod; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
@@ -18,13 +18,15 @@ | |||||
package org.apache.tools.ant.taskdefs.optional.repository; | package org.apache.tools.ant.taskdefs.optional.repository; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.types.Path; | |||||
import java.io.File; | import java.io.File; | ||||
/** | /** | ||||
* How we represent libraries | * How we represent libraries | ||||
* | * | ||||
* @since 20-Oct-2004 | |||||
* @since Ant1.7 | |||||
*/ | */ | ||||
public class Library { | public class Library { | ||||
@@ -44,8 +46,21 @@ public class Library { | |||||
private String destinationName; | private String destinationName; | ||||
/** | |||||
* file mapped to this one | |||||
*/ | |||||
private File libraryFile; | private File libraryFile; | ||||
/** | |||||
* if clause | |||||
*/ | |||||
private String ifClause; | |||||
/** | |||||
* unless clause | |||||
*/ | |||||
private String unlessClause; | |||||
public static final String ERROR_NO_ARCHIVE = "No archive defined"; | public static final String ERROR_NO_ARCHIVE = "No archive defined"; | ||||
public static final String ERROR_NO_PROJECT = "No project defined"; | public static final String ERROR_NO_PROJECT = "No project defined"; | ||||
public static final String ERROR_NO_VERSION = "No version defined"; | public static final String ERROR_NO_VERSION = "No version defined"; | ||||
@@ -57,40 +72,73 @@ public class Library { | |||||
private String suffix = "jar"; | private String suffix = "jar"; | ||||
/** | |||||
* the project that provides this library | |||||
* @return the project or null | |||||
*/ | |||||
public String getProject() { | public String getProject() { | ||||
return project; | return project; | ||||
} | } | ||||
/** | |||||
* the project that provides this library | |||||
* @param project | |||||
*/ | |||||
public void setProject(String project) { | public void setProject(String project) { | ||||
this.project = project; | this.project = project; | ||||
} | } | ||||
/** | |||||
* Get the version string of this library | |||||
* @return | |||||
*/ | |||||
public String getVersion() { | public String getVersion() { | ||||
return version; | return version; | ||||
} | } | ||||
/** | |||||
* set the version string of this library | |||||
* @param version | |||||
*/ | |||||
public void setVersion(String version) { | public void setVersion(String version) { | ||||
this.version = version; | this.version = version; | ||||
} | } | ||||
/** | |||||
* get the base name of this library | |||||
* @return | |||||
*/ | |||||
public String getArchive() { | public String getArchive() { | ||||
return archive; | return archive; | ||||
} | } | ||||
/** | |||||
* set the base name of this library | |||||
* @param archive | |||||
*/ | |||||
public void setArchive(String archive) { | public void setArchive(String archive) { | ||||
this.archive = archive; | this.archive = archive; | ||||
} | } | ||||
/** | |||||
* get the destination name attribute. | |||||
* @return | |||||
*/ | |||||
public String getDestinationName() { | public String getDestinationName() { | ||||
return destinationName; | return destinationName; | ||||
} | } | ||||
/** | |||||
* set the name of the library when downloaded, | |||||
* relative to the base directory | |||||
* @param destinationName | |||||
*/ | |||||
public void setDestinationName(String destinationName) { | public void setDestinationName(String destinationName) { | ||||
this.destinationName = destinationName; | this.destinationName = destinationName; | ||||
} | } | ||||
/** | /** | ||||
* get the suffix for this file. | |||||
* get the suffix for this file. | |||||
* | * | ||||
* @return | * @return | ||||
*/ | */ | ||||
@@ -98,10 +146,51 @@ public class Library { | |||||
return suffix; | return suffix; | ||||
} | } | ||||
/** | |||||
* set the suffix for this file; default is "jar" | |||||
* @param suffix | |||||
*/ | |||||
public void setSuffix(String suffix) { | public void setSuffix(String suffix) { | ||||
this.suffix = suffix; | 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) | |||||
* @return library file or null | |||||
*/ | |||||
public File getLibraryFile() { | public File getLibraryFile() { | ||||
return libraryFile; | return libraryFile; | ||||
} | } | ||||
@@ -132,6 +221,10 @@ public class Library { | |||||
faultIfEmpty(version, ERROR_NO_SUFFIX); | faultIfEmpty(version, ERROR_NO_SUFFIX); | ||||
} | } | ||||
/** | |||||
* string is for debug | |||||
* @return | |||||
*/ | |||||
public String toString() { | public String toString() { | ||||
return "Library " + getNormalFilename() | return "Library " + getNormalFilename() | ||||
+ " from project " + project | + " from project " + project | ||||
@@ -139,9 +232,10 @@ public class Library { | |||||
} | } | ||||
/** | /** | ||||
* calculare the destination file of a library | |||||
* calculate the destination file of a library; set {@link #libraryFile} | |||||
* to the File thereof. | |||||
* | * | ||||
* @param baseDir | |||||
* @param baseDir dir that | |||||
* | * | ||||
* @throws BuildException if invalid | * @throws BuildException if invalid | ||||
*/ | */ | ||||
@@ -154,7 +248,8 @@ public class Library { | |||||
} | } | ||||
/** | /** | ||||
* a test that is only valid after binding | |||||
* Test for a library | |||||
* only valid after binding | |||||
* | * | ||||
* @return | * @return | ||||
*/ | */ | ||||
@@ -164,7 +259,7 @@ public class Library { | |||||
/** | /** | ||||
* get the last modified date | * get the last modified date | ||||
* | |||||
* only valid after binding | |||||
* @return | * @return | ||||
*/ | */ | ||||
public long getLastModified() { | public long getLastModified() { | ||||
@@ -215,4 +310,30 @@ public class Library { | |||||
return libraryFile.getAbsolutePath(); | return libraryFile.getAbsolutePath(); | ||||
} | } | ||||
/** | |||||
* test for being enabled | |||||
* @param project | |||||
* @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; | |||||
} | |||||
/** | |||||
* add our location to a filepath | |||||
* @param path | |||||
*/ | |||||
public void appendToPath(Path path) { | |||||
Path.PathElement pathElement = path.createPathElement(); | |||||
pathElement.setLocation(getLibraryFile()); | |||||
} | |||||
} | } |
@@ -67,17 +67,19 @@ public class GetLibrariesTest extends BuildFileTest { | |||||
* refs are broken | * refs are broken | ||||
* */ | * */ | ||||
public void NotestFunctionalInline() { | public void NotestFunctionalInline() { | ||||
if(offline()) { | |||||
return; | |||||
} | |||||
executeTarget("testFunctionalInline"); | |||||
execIfOnline("testFunctionalInline"); | |||||
} | } | ||||
public void testMavenInline() { | public void testMavenInline() { | ||||
String targetName = "testMavenInline"; | |||||
execIfOnline(targetName); | |||||
} | |||||
private void execIfOnline(String targetName) { | |||||
if (offline()) { | if (offline()) { | ||||
return; | return; | ||||
} | } | ||||
executeTarget("testMavenInline"); | |||||
executeTarget(targetName); | |||||
} | } | ||||
public void testTwoRepositories() { | public void testTwoRepositories() { | ||||
@@ -93,16 +95,24 @@ public class GetLibrariesTest extends BuildFileTest { | |||||
} | } | ||||
public void testRenaming() { | public void testRenaming() { | ||||
if (offline()) { | |||||
return; | |||||
} | |||||
executeTarget("testRenaming"); | |||||
execIfOnline("testRenaming"); | |||||
} | } | ||||
public void testOverwrite() { | public void testOverwrite() { | ||||
if (offline()) { | |||||
return; | |||||
} | |||||
executeTarget("testOverwrite"); | |||||
execIfOnline("testOverwrite"); | |||||
} | } | ||||
public void testIf() { | |||||
execIfOnline("testIf"); | |||||
} | |||||
public void testUnless() { | |||||
execIfOnline("testUnless"); | |||||
} | |||||
public void testPathID() { | |||||
execIfOnline("testPathID"); | |||||
} | |||||
} | } |