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"?> | |||
<project name="getlibraries" basedir="." default="all"> | |||
<project name="getlibraries" basedir="." default="init"> | |||
<!-- use the normal one at ibiblio--> | |||
@@ -10,12 +10,17 @@ | |||
<mkdir dir="${lib.dir}"/> | |||
<property name="commons.logging" value="commons-logging-1.0.1.jar"/> | |||
<presetdef name="getlib"> | |||
<presetdef name="gl1"> | |||
<getlibraries destDir="${lib.dir}"> | |||
<library archive="commons-logging" project="commons-logging" version="1.0.1"/> | |||
</getlibraries> | |||
</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"> | |||
<attribute name="library" default="${commons.logging}"/> | |||
<sequential> | |||
@@ -26,6 +31,18 @@ | |||
</fail> | |||
</sequential> | |||
</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 name="cleanup"> | |||
@@ -108,5 +125,37 @@ | |||
</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"/> | |||
</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> | |||
@@ -19,13 +19,16 @@ 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.types.Path; | |||
import org.apache.tools.ant.types.Reference; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Collection; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import java.util.NoSuchElementException; | |||
/** | |||
* This task will retrieve one or more libraries from a repository. <ol> | |||
@@ -64,6 +67,13 @@ public class GetLibraries extends Task { | |||
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_NO_DEST_DIR = "No destination directory"; | |||
public static final String ERROR_NO_REPOSITORY = "No repository defined"; | |||
@@ -167,18 +177,47 @@ public class GetLibraries extends Task { | |||
return destDir; | |||
} | |||
/** | |||
* get fore download flag | |||
* @return | |||
*/ | |||
public boolean isForceDownload() { | |||
return forceDownload; | |||
} | |||
/** | |||
* get the list of libraries | |||
* @return | |||
*/ | |||
public List getLibraries() { | |||
return libraries; | |||
} | |||
/** | |||
* get our repository | |||
* @return | |||
*/ | |||
public Repository getRepository() { | |||
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 | |||
* | |||
@@ -208,17 +247,17 @@ public class GetLibraries extends Task { | |||
validate(); | |||
Repository repo = repository.resolve(); | |||
repo.validate(); | |||
int toFetch = libraries.size(); | |||
if (toFetch == 0) { | |||
if (libraries.size() == 0) { | |||
throw new BuildException(ERROR_NO_LIBRARIES); | |||
} | |||
int fetched = 0; | |||
int failures = 0; | |||
log("Getting libraries from " + repo.toString(), Project.MSG_VERBOSE); | |||
log("Saving libraries to " + destDir.toString(), Project.MSG_VERBOSE); | |||
bindAllLibraries(); | |||
if (isOffline()) { | |||
log("No retrieval, task is \"offline\""); | |||
//when offline, we just make sure everything is in place | |||
verifyAllLibrariesPresent(); | |||
return; | |||
} | |||
@@ -250,18 +289,19 @@ public class GetLibraries extends Task { | |||
} | |||
//iterate through the libs we have | |||
Iterator it = libraries.iterator(); | |||
Iterator it = filteredIterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
library.bind(destDir); | |||
try { | |||
//fetch it | |||
if (repo.fetch(library)) { | |||
fetched++; | |||
} | |||
} 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++; | |||
} | |||
} | |||
} finally { | |||
@@ -270,12 +310,18 @@ public class GetLibraries extends Task { | |||
//at this point downloads have finished. | |||
//we do still need to verify that everything worked. | |||
if ((fetched < toFetch && forceDownload)) { | |||
if ((failures>0 && forceDownload)) { | |||
throw new BuildException(ERROR_FORCED_DOWNLOAD_FAILED); | |||
} | |||
//validate the download | |||
verifyAllLibrariesPresent(); | |||
//create the path | |||
if(pathid!=null) { | |||
createPath(); | |||
} | |||
} | |||
/** | |||
@@ -296,7 +342,7 @@ public class GetLibraries extends Task { | |||
//iterate through the libs we have | |||
boolean missing = false; | |||
Iterator it = libraries.iterator(); | |||
Iterator it = filteredIterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
//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; | |||
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.methods.GetMethod; | |||
import org.apache.tools.ant.BuildException; | |||
@@ -18,13 +18,15 @@ | |||
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.types.Path; | |||
import java.io.File; | |||
/** | |||
* How we represent libraries | |||
* | |||
* @since 20-Oct-2004 | |||
* @since Ant1.7 | |||
*/ | |||
public class Library { | |||
@@ -44,8 +46,21 @@ public class Library { | |||
private String destinationName; | |||
/** | |||
* file mapped to this one | |||
*/ | |||
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_PROJECT = "No project defined"; | |||
public static final String ERROR_NO_VERSION = "No version defined"; | |||
@@ -57,40 +72,73 @@ public class Library { | |||
private String suffix = "jar"; | |||
/** | |||
* the project that provides this library | |||
* @return the project or null | |||
*/ | |||
public String getProject() { | |||
return project; | |||
} | |||
/** | |||
* the project that provides this library | |||
* @param project | |||
*/ | |||
public void setProject(String project) { | |||
this.project = project; | |||
} | |||
/** | |||
* Get the version string of this library | |||
* @return | |||
*/ | |||
public String getVersion() { | |||
return version; | |||
} | |||
/** | |||
* set the version string of this library | |||
* @param version | |||
*/ | |||
public void setVersion(String version) { | |||
this.version = version; | |||
} | |||
/** | |||
* get the base name of this library | |||
* @return | |||
*/ | |||
public String getArchive() { | |||
return archive; | |||
} | |||
/** | |||
* set the base name of this library | |||
* @param archive | |||
*/ | |||
public void setArchive(String archive) { | |||
this.archive = archive; | |||
} | |||
/** | |||
* get the destination name attribute. | |||
* @return | |||
*/ | |||
public String getDestinationName() { | |||
return destinationName; | |||
} | |||
/** | |||
* set the name of the library when downloaded, | |||
* relative to the base directory | |||
* @param destinationName | |||
*/ | |||
public void setDestinationName(String destinationName) { | |||
this.destinationName = destinationName; | |||
} | |||
/** | |||
* get the suffix for this file. | |||
* get the suffix for this file. | |||
* | |||
* @return | |||
*/ | |||
@@ -98,10 +146,51 @@ public class Library { | |||
return suffix; | |||
} | |||
/** | |||
* set the suffix for this file; default is "jar" | |||
* @param suffix | |||
*/ | |||
public void setSuffix(String 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() { | |||
return libraryFile; | |||
} | |||
@@ -132,6 +221,10 @@ public class Library { | |||
faultIfEmpty(version, ERROR_NO_SUFFIX); | |||
} | |||
/** | |||
* string is for debug | |||
* @return | |||
*/ | |||
public String toString() { | |||
return "Library " + getNormalFilename() | |||
+ " 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 | |||
*/ | |||
@@ -154,7 +248,8 @@ public class Library { | |||
} | |||
/** | |||
* a test that is only valid after binding | |||
* Test for a library | |||
* only valid after binding | |||
* | |||
* @return | |||
*/ | |||
@@ -164,7 +259,7 @@ public class Library { | |||
/** | |||
* get the last modified date | |||
* | |||
* only valid after binding | |||
* @return | |||
*/ | |||
public long getLastModified() { | |||
@@ -215,4 +310,30 @@ public class Library { | |||
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 | |||
* */ | |||
public void NotestFunctionalInline() { | |||
if(offline()) { | |||
return; | |||
} | |||
executeTarget("testFunctionalInline"); | |||
execIfOnline("testFunctionalInline"); | |||
} | |||
public void testMavenInline() { | |||
String targetName = "testMavenInline"; | |||
execIfOnline(targetName); | |||
} | |||
private void execIfOnline(String targetName) { | |||
if (offline()) { | |||
return; | |||
} | |||
executeTarget("testMavenInline"); | |||
executeTarget(targetName); | |||
} | |||
public void testTwoRepositories() { | |||
@@ -93,16 +95,24 @@ public class GetLibrariesTest extends BuildFileTest { | |||
} | |||
public void testRenaming() { | |||
if (offline()) { | |||
return; | |||
} | |||
executeTarget("testRenaming"); | |||
execIfOnline("testRenaming"); | |||
} | |||
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"); | |||
} | |||
} |