You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by st...@apache.org on 2004/10/26 01:13:39 UTC
cvs commit: ant/src/etc/testcases/taskdefs/optional getlibraries.xml
stevel 2004/10/25 16:13:39
Modified: src/main/org/apache/tools/ant/types defaults.properties
src/main/org/apache/tools/ant/taskdefs defaults.properties
. build.xml WHATSNEW
Added: src/main/org/apache/tools/ant/taskdefs/optional/repository
GetLibraries.java HttpRepository.java Library.java
MavenRepository.java Repository.java
RepositoryRef.java
src/testcases/org/apache/tools/ant/taskdefs/optional
GetLibrariesTest.java
src/etc/testcases/taskdefs/optional getlibraries.xml
Log:
Repository support; needs http client 2.x and commons-logging.
Broken: repository references (you'll see in the test results)
not tested: authenticated access to the repository.
Already had a feature request for multiple repository support;
would be nice. That and better diagnostics on failure.
Note that we dont currently probe ibiblio for availaibility; that was taking longer than the fetches themselves.
Revision Changes Path
1.1 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/GetLibraries.java
Index: GetLibraries.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.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.Reference;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* This task will retrieve one or more libraries from a repository. <ol>
* <li>Users must declare a repository, either inline or by reference</li>
* <li>Dependency checking is used (timestamps) unless forceDownload=true</li>
* <li>It is an error if, at the end of the task, a library is missing.
*
* @ant.task
* @since Ant 1.7
*/
public class GetLibraries extends Task {
/**
* destination
*/
private File destDir;
/**
* flag to force a download
*/
private boolean forceDownload = false;
/**
* flag to force offline
*/
private boolean offline = false;
/**
* list of libraries
*/
private List libraries = new LinkedList();
/**
* repository for retrieval
*/
private Repository repository;
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";
/**
* add a repository. Only one is (currently) supported
*
* @param repo
*/
public void add(Repository repo) {
if (repository != null) {
throw new BuildException(ERROR_ONE_REPOSITORY_ONLY);
}
repository = repo;
}
/**
* add a repository. Unless there is explicit support for a subclass
*
* @param repo
*/
public void addRepository(RepositoryRef repo) {
add(repo);
}
/**
* add a maven repository.
*/
/*
public void addMavenRepository(MavenRepository repo) {
add(repo);
}
*/
/**
* bind to a repository.
*/
public void setRepositoryRef(final Reference ref) {
//create a special repository that can only
//resolve references.
Repository r = new RepositoryRef(getProject(), ref);
add(r);
}
/**
* add a library for retrieval
*
* @param lib
*/
public void addLibrary(Library lib) {
libraries.add(lib);
}
/**
* destination directory for all library files
*
* @param destDir
*/
public void setDestDir(File destDir) {
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
*
* @return true if the offline flag is set
*/
public boolean isOffline() {
return offline;
}
/**
* declare the system offline. This disables any attempt to retrieve files.
* In this mode, only the presence of files is verified. If forceDownload is
* true, or there is a missing library, then an error will be raised.
*
* @param offline
*/
public void setOffline(boolean offline) {
this.offline = offline;
}
public File getDestDir() {
return destDir;
}
public boolean isForceDownload() {
return forceDownload;
}
public List getLibraries() {
return libraries;
}
public Repository getRepository() {
return repository;
}
/**
* validate ourselves
*
* @throws BuildException
*/
public void validate() {
if (destDir == null || !destDir.exists() || !destDir.isDirectory()) {
throw new BuildException(ERROR_NO_DEST_DIR);
}
if (repository == null) {
throw new BuildException(ERROR_NO_REPOSITORY);
}
Iterator it = libraries.iterator();
while (it.hasNext()) {
Library library = (Library) it.next();
library.validate();
}
}
/**
* Called by the project to let the task do its work.
*
* @throws org.apache.tools.ant.BuildException
* if something goes wrong with the build
*/
public void execute() throws BuildException {
validate();
Repository repo = repository.resolve();
repo.validate();
int toFetch = libraries.size();
if (toFetch == 0) {
throw new BuildException(ERROR_NO_LIBRARIES);
}
int fetched = 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\"");
verifyAllLibrariesPresent();
return;
}
//connect the repository
repo.connect(this);
try {
//check for reachability.
//it is up to each repository to decide that.
boolean reachable;
try {
log("Checking repository for reachability", Project.MSG_DEBUG);
reachable = repo.checkRepositoryReachable();
} catch (IOException e) {
log(ERROR_REPO_PROBE_FAILED + e.getMessage(),
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);
}
//iterate through the libs we have
Iterator it = libraries.iterator();
while (it.hasNext()) {
Library library = (Library) it.next();
library.bind(destDir);
try {
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);
}
}
} finally {
repo.disconnect();
}
//at this point downloads have finished.
//we do still need to verify that everything worked.
if ((fetched < toFetch && forceDownload)) {
throw new BuildException(ERROR_FORCED_DOWNLOAD_FAILED);
}
verifyAllLibrariesPresent();
}
/**
* bind all libraries to our destination
*/
protected void bindAllLibraries() {
Iterator it = libraries.iterator();
while (it.hasNext()) {
Library library = (Library) it.next();
library.bind(destDir);
}
}
/**
* verify that all libraries are present
*/
protected void verifyAllLibrariesPresent() {
//iterate through the libs we have
boolean missing = false;
Iterator it = libraries.iterator();
while (it.hasNext()) {
Library library = (Library) it.next();
//check for the library existing
if (!library.exists()) {
//and log if one is missing
log("Missing: " + library.toString(),
Project.MSG_ERR);
missing = true;
}
}
if (missing) {
throw new BuildException(ERROR_INCOMPLETE_RETRIEVAL);
}
}
}
1.1 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/HttpRepository.java
Index: HttpRepository.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional.repository;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.FileUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
/**
* This is a base class for repositories that are built on URLs. Although you
* can share this datatype, it is *not* thread safe; you can only use it in one
* thread at at time
*
* @since Ant1.7
*/
public abstract class HttpRepository extends Repository {
/**
* repositoryURL of repository
*/
private String url;
/**
* username
*/
private String username;
/**
* password
*/
private String password;
/**
* auth realm; can be null
*/
private String realm;
/**
* this is our http client
*/
private HttpClient client;
/**
* number of times to retry fetches
*/
private int retries = 1;
/**
* no repository URL
*/
public static final String ERROR_NO_REPOSITORY_URL = "No repository URL";
/**
* owner class
*/
private GetLibraries owner;
/**
* retry logic
*/
private DefaultMethodRetryHandler retryhandler;
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
*
* @return
*/
public String getUrl() {
return url;
}
/**
* Set the base URL of the repository
*
* @param url
*/
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
/**
* set the username for the remote repository
*
* @param username
*/
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
/**
* set the password for the remote repository
*
* @param password
*/
public void setPassword(String password) {
this.password = password;
}
public String getRealm() {
return realm;
}
/**
* set the realm for authentication; empty string is equivalent to "any
* realm" (the default)
*
* @param realm
*/
public void setRealm(String realm) {
if (realm != null) {
this.realm = realm;
} else {
this.realm = null;
}
}
/**
* @return number of times to retry fetches
*/
public int getRetries() {
return retries;
}
/**
* number of times to retry fetches
*
* @param retries
*/
public void setRetries(int retries) {
this.retries = retries;
}
/**
* get the client
*
* @return
*/
public HttpClient getClient() {
return client;
}
public GetLibraries getOwner() {
return owner;
}
/**
* validate yourself
*
* @throws org.apache.tools.ant.BuildException
* if unhappy
*/
public void validate() {
super.validate();
checkChildrenAllowed();
checkAttributesAllowed();
if (url == null || url.length() == 0) {
throw new BuildException(ERROR_NO_REPOSITORY_URL);
}
}
/**
* override point: connection is called at the start of the retrieval
* process
*
* @param newOwner
*
* @throws org.apache.tools.ant.BuildException
*
*/
public void connect(GetLibraries newOwner) {
this.owner = newOwner;
if (client != null) {
throw new BuildException(ERROR_REENTRANT_USE);
}
if (!url.endsWith("/")) {
url = url + '/';
}
client = new HttpClient();
//retry handler
retryhandler = new DefaultMethodRetryHandler();
retryhandler.setRequestSentRetryEnabled(false);
retryhandler.setRetryCount(retries);
//validate the URL
URL repository;
try {
repository = new URL(url);
} catch (MalformedURLException e) {
throw new BuildException(e);
}
//authentication
if (username != null) {
Credentials defaultcreds =
new UsernamePasswordCredentials(username, password);
client.getState().setCredentials(realm,
repository.getHost(),
defaultcreds);
//turn auth on on first call
client.getState().setAuthenticationPreemptive(true);
}
//cookies
client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY);
}
/**
* override point: connection is called at the start of the retrieval
* process
*
* @throws org.apache.tools.ant.BuildException
*
*/
public void disconnect() {
client = null;
retryhandler = null;
}
/**
* Test for a repository being reachable. This method is called after {@link
* #connect(org.apache.tools.ant.taskdefs.optional.repository.GetLibraries)}
* is called, before any files are to be retrieved.
* <p/>
* If it returns false the repository considers itself offline. Similarly,
* any ioexception is interpreted as being offline.
* <p/>
* The Http implementation probes for the base URL being reachable, and
* returning a 200 status code.
*
* @return true if the repository is online.
*
* @throws java.io.IOException
*/
public boolean checkRepositoryReachable() throws IOException {
//return pingBaseURL();
return true;
}
private boolean pingBaseURL() throws IOException {
GetMethod get = createGet(getUrl());
client.executeMethod(get);
return get.getStatusCode() == HttpStatus.SC_OK;
}
/**
* create a new getMethod against any URI
*
* @param url
*
* @return
*/
public GetMethod createGet(String url) {
GetMethod method = new GetMethod(url);
method.setMethodRetryHandler(retryhandler);
method.setDoAuthentication(true);
method.setFollowRedirects(true);
return method;
}
/**
* @param method
* @param timestamp
*
* @link http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#if-modified-since
* @link http://www.w3.org/Protocols/rfc850/rfc850.html#z10
*/
public void setIfModifiedSinceHeader(HttpMethod method, long timestamp) {
Date date = new Date(timestamp);
//ooh, naughty, deprecated. and like why is it deprecated?
method.setRequestHeader(IF_MODIFIED_SINCE, date.toGMTString());
}
/**
* fetch a library from the repository
*
* @param library
*
* @return true if we retrieved
*
* @throws org.apache.tools.ant.BuildException
*
*/
public boolean fetch(Library library) throws IOException {
String path = getRemoteLibraryURL(library);
logVerbose("Library URL=" + path);
logVerbose("destination =" + library.getAbsolutePath());
GetMethod get = createGet(path);
boolean useTimestamps = !getOwner().isForceDownload() &&
!library.exists();
if (useTimestamps) {
setIfModifiedSinceHeader(get, library.getLastModified());
}
try {
long start, finish;
start = System.currentTimeMillis();
client.executeMethod(get);
if (useTimestamps && get.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) {
logDebug("File is not modified");
//we get here if there is no change in timestamp
//so no fetch
return false;
}
if (get.getStatusCode() != HttpStatus.SC_OK) {
String message = "Request Failed:"
+ get.getStatusCode()
+ " from " + get.getPath();
logVerbose(message);
logVerbose(get.getStatusLine().toString());
logVerbose(get.getStatusText());
throw new BuildException(message);
}
saveStreamToLibrary(get, library);
finish = System.currentTimeMillis();
long diff = finish - start;
logVerbose("downloaded in " + diff / 1000 + " seconds");
} finally {
// Release the connection.
get.releaseConnection();
}
return true;
}
/**
* log something at the verbose level
*
* @param message text to log
*/
protected void logVerbose(String message) {
getOwner().log(message,
Project.MSG_VERBOSE);
}
protected void logDebug(String message) {
getOwner().log(message,
Project.MSG_DEBUG);
}
/**
* Get the path to a remote library. This is the full URL
*
* @param library
*
* @return URL to library
*/
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.
*/
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");
}
}
/**
* Returns a string representation of the repository
*
* @return the base URL
*/
public String toString() {
return "Repository at " + getUrl();
}
}
1.1 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/Library.java
Index: Library.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional.repository;
import org.apache.tools.ant.BuildException;
import java.io.File;
/**
* How we represent libraries
*
* @since 20-Oct-2004
*/
public class Library {
//project "ant"
private String project;
//version "1.5"
private String version;
//archive prefix "ant-optional"
private String archive;
/**
* very optional attribute; name of the destination. Autocalculated if not
* set.
*/
private String destinationName;
private File libraryFile;
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";
public static final String ERROR_NO_SUFFIX = "No version defined";
/**
* suffix
*/
private String suffix = "jar";
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getArchive() {
return archive;
}
public void setArchive(String archive) {
this.archive = archive;
}
public String getDestinationName() {
return destinationName;
}
public void setDestinationName(String destinationName) {
this.destinationName = destinationName;
}
/**
* get the suffix for this file.
*
* @return
*/
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public File getLibraryFile() {
return libraryFile;
}
/**
* fault if the field is null or empty
*
* @param field
* @param message text for fault
*
* @throws BuildException if the field is not set up
*/
private void faultIfEmpty(String field, String message) {
if (field == null || field.length() == 0) {
throw new BuildException(message);
}
}
/**
* validate;
*
* @throws BuildException if invalid
*/
public void validate() {
faultIfEmpty(archive, ERROR_NO_ARCHIVE);
faultIfEmpty(project, ERROR_NO_PROJECT);
faultIfEmpty(version, ERROR_NO_VERSION);
faultIfEmpty(version, ERROR_NO_SUFFIX);
}
public String toString() {
return "Library " + getNormalFilename()
+ " from project " + project
+ " to " + getDestinationName();
}
/**
* calculare the destination file of a library
*
* @param baseDir
*
* @throws BuildException if invalid
*/
public void bind(File baseDir) {
validate();
if (destinationName == null) {
destinationName = getNormalFilename();
}
libraryFile = new File(baseDir, destinationName);
}
/**
* a test that is only valid after binding
*
* @return
*/
public boolean exists() {
return libraryFile.exists();
}
/**
* get the last modified date
*
* @return
*/
public long getLastModified() {
return libraryFile.lastModified();
}
/**
* get the filename from the rule of archive+version+'.'+suffix. Clearly
* only valid if all fields are defined.
*
* @return a string representing the expected name of the file at the
* source
*/
public String getNormalFilename() {
return archive + "-" + version + "." + suffix;
}
/**
* get the filename of the destination; no path.
*
* @return
*/
public String getDestFilename() {
if (destinationName == null) {
return getNormalFilename();
} else {
return destinationName;
}
}
/**
* get a maven path (project/filename)
*
* @param separator directory separator
*
* @return
*/
public String getMavenPath(char separator) {
return project + separator + "jars" + separator + getNormalFilename();
}
/**
* get the absolute path of this library
*
* @return
*/
public String getAbsolutePath() {
return libraryFile.getAbsolutePath();
}
}
1.1 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/MavenRepository.java
Index: MavenRepository.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional.repository;
/**
* A Maven repository knows about maven repository layout rules It also defaults
* to http://www.ibiblio.org/maven/
*
* @link http://maven.apache.org/reference/user-guide.html#Remote_Repository_Layout
* @link
* @since Ant1.7
*/
public class MavenRepository extends HttpRepository {
public static final String MAVEN_URL = "http://www.ibiblio.org/maven/";
/**
* bind to the main maven repository
*/
public MavenRepository() {
setUrl(MAVEN_URL);
}
/**
* Get the path to a remote library. This is the full URL
*
* @param library
*
* @return URL to library
*/
protected String getRemoteLibraryURL(Library library) {
String base = getUrl();
if (!base.endsWith("/")) {
base = base + '/';
}
return base + library.getMavenPath('/');
}
/**
* Returns a string representation of the repository
*
* @return the base URL
*/
public String toString() {
return "Maven Repository at " + getUrl();
}
}
1.1 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/Repository.java
Index: Repository.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional.repository;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.DataType;
import java.io.IOException;
/**
* This type represents a repository; a place that stores libraries for
* retrieval. To use this type, you must use a non-abstract class, either one
* that ships with Ant, or one you implement and declare yourself.
* <p/>
* The <getlibraries> task lets you supply a repository by reference
* inline {@link GetLibraries#add(Repository)} or on the command line {@link
* GetLibraries#setRepositoryRef(org.apache.tools.ant.types.Reference)}
*
* @since Ant1.7
*/
public abstract class Repository extends DataType {
/**
* validate yourself
*
* @throws BuildException if unhappy
*/
public void validate() {
}
/**
* recursively resolve any references to get the real repository
*
* @return
*/
public final Repository resolve() {
if (getRefid() == null) {
return this;
} else {
Repository repository = (Repository) getCheckedRef(this.getClass(),
"Repository");
return repository;
}
}
/**
* override point: connection is called at the start of the retrieval
* process
*
* @param owner owner of the libraries
*
* @throws BuildException
*/
public void connect(GetLibraries owner) {
}
/**
* override point: connection is called at the start of the retrieval
* process
*
* @throws BuildException
*/
public void disconnect() {
}
/**
* Test for a repository being reachable. This method is called after {@link
* #connect(GetLibraries)} is called, before any files are to be retrieved.
* <p/>
* If it returns false the repository considers itself offline. Similarly,
* any ioexception is interpreted as being offline.
*
* @return true if the repository is online.
*
* @throws IOException
*/
public abstract boolean checkRepositoryReachable() throws IOException;
/**
* fetch a library from the repository
*
* @param library
*
* @return
*/
public abstract boolean fetch(Library library) throws IOException;
}
1.1 ant/src/main/org/apache/tools/ant/taskdefs/optional/repository/RepositoryRef.java
Index: RepositoryRef.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional.repository;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Reference;
import java.io.IOException;
/**
* not a real repository; one to paste a reference into the chain for
* resolution.
*
* @since Ant1.7
*/
public final class RepositoryRef extends Repository {
/**
* create a repository reference
*
* @param reference
*/
public RepositoryRef(Project project, Reference reference) {
setRefid(reference);
setProject(project);
}
/**
* empty constructor
*/
public RepositoryRef() {
}
/**
* Test for a repository being reachable. This method is called after {@link
* #connect(GetLibraries)} is called, before any files are to be retrieved.
* <p/>
* If it returns false the repository considers itself offline. Similarly,
* any ioexception is interpreted as being offline.
*
* @return true if the repository is online.
*
* @throws java.io.IOException
*/
public boolean checkRepositoryReachable() throws IOException {
return false;
}
/**
* fetch a library from the repository
*
* @param library
*
* @return
*/
public boolean fetch(Library library) throws IOException {
throw new BuildException("Not Implemented");
}
}
1.1 ant/src/testcases/org/apache/tools/ant/taskdefs/optional/GetLibrariesTest.java
Index: GetLibrariesTest.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional;
import org.apache.tools.ant.BuildFileTest;
import org.apache.tools.ant.taskdefs.optional.repository.GetLibraries;
/**
* test the test libraries stuff.
* skip all the tests if we are offline
*/
public class GetLibrariesTest extends BuildFileTest {
private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/";
public GetLibrariesTest(String name) {
super(name);
}
public void setUp() {
configureProject(TASKDEFS_DIR + "getlibraries.xml");
}
protected boolean offline() {
return "true".equals(System.getProperty("offline"));
}
public void tearDown() {
executeTarget("cleanup");
}
public void testEmpty() {
expectBuildException("testEmpty",GetLibraries.ERROR_NO_DEST_DIR);
}
public void testEmpty2() {
expectBuildException("testEmpty2", GetLibraries.ERROR_NO_REPOSITORY);
}
public void testEmpty3() {
expectBuildException("testEmpty3", GetLibraries.ERROR_NO_LIBRARIES);
}
public void testNoRepo() {
expectBuildException("testNoRepo", GetLibraries.ERROR_NO_REPOSITORY);
}
public void testUnknownReference() {
expectBuildException("testUnknownReference", "Reference unknown not found.");
}
/**
* refs are broken
* */
public void testFunctionalInline() {
if(offline()) {
return;
}
executeTarget("testFunctionalInline");
}
public void testMavenInline() {
if (offline()) {
return;
}
executeTarget("testMavenInline");
}
public void testTwoRepositories() {
expectBuildException("testTwoRepositories", GetLibraries.ERROR_ONE_REPOSITORY_ONLY);
}
public void testMavenInlineBadURL() {
if (offline()) {
return;
}
expectBuildException("testTwoRepositories",
GetLibraries.ERROR_INCOMPLETE_RETRIEVAL);
}
public void testRenaming() {
if (offline()) {
return;
}
executeTarget("testRenaming");
}
public void testOverwrite() {
if (offline()) {
return;
}
executeTarget("testOverwrite");
}
}
1.27 +2 -1 ant/src/main/org/apache/tools/ant/types/defaults.properties
Index: defaults.properties
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/defaults.properties,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- defaults.properties 13 Oct 2004 05:53:52 -0000 1.26
+++ defaults.properties 25 Oct 2004 23:13:38 -0000 1.27
@@ -33,4 +33,5 @@
propertyset=org.apache.tools.ant.types.PropertySet
assertions=org.apache.tools.ant.types.Assertions
concatfilter=org.apache.tools.ant.filters.ConcatFilter
-ispingable=org.apache.tools.ant.taskdefs.optional.condition.IsPingable
\ No newline at end of file
+ispingable=org.apache.tools.ant.taskdefs.optional.condition.IsPingable
+mavenrepository=org.apache.tools.ant.taskdefs.optional.repository.MavenRepository
\ No newline at end of file
1.159 +1 -0 ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties
Index: defaults.properties
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
retrieving revision 1.158
retrieving revision 1.159
diff -u -r1.158 -r1.159
--- defaults.properties 8 Oct 2004 16:40:07 -0000 1.158
+++ defaults.properties 25 Oct 2004 23:13:38 -0000 1.159
@@ -203,6 +203,7 @@
scriptdef=org.apache.tools.ant.taskdefs.optional.script.ScriptDef
ildasm=org.apache.tools.ant.taskdefs.optional.dotnet.Ildasm
apt=org.apache.tools.ant.taskdefs.Apt
+getlibraries=org.apache.tools.ant.taskdefs.optional.repository.GetLibraries
# deprecated ant tasks (kept for back compatibility)
starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
1.434 +21 -0 ant/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/ant/build.xml,v
retrieving revision 1.433
retrieving revision 1.434
diff -u -r1.433 -r1.434
--- build.xml 19 Oct 2004 14:29:21 -0000 1.433
+++ build.xml 25 Oct 2004 23:13:38 -0000 1.434
@@ -328,6 +328,11 @@
<filename name="${ant.package}/launch/**/*"/>
</selector>
+ <selector id="needs.commons.httpclient">
+ <filename name="${optional.package}/repository/**/*"/>
+ </selector>
+
+
<patternset id="onlinetests">
<exclude name="**/GetTest.java" if="offline"/>
<exclude name="**/SignJarTest.java" if="offline"/>
@@ -561,6 +566,17 @@
classpathref="classpath"/>
</or>
</condition>
+
+ <!-- http client needs commons logging -->
+ <condition property="commons.httpclient.present">
+ <and>
+ <available
+ classname="org.apache.commons.httpclient.HttpClient"
+ classpathref="classpath"/>
+ <isset property="commons.logging.present"/>
+ </and>
+ </condition>
+
<condition property="wsdl.found">
<or>
<available file="wsdl" filepath="${env.PATH}"/>
@@ -679,6 +695,7 @@
<selector refid="needs.jdepend" unless="jdepend.present"/>
<selector refid="needs.swing" unless="swing.present"/>
<selector refid="needs.jsch" unless="jsch.present"/>
+ <selector refid="needs.commons.httpclient" unless="commons.httpclient.present"/>
</or>
</not>
</selector>
@@ -853,6 +870,7 @@
<selector refid="needs.jdepend"/>
<selector refid="needs.swing"/>
<selector refid="needs.jsch"/>
+ <selector refid="needs.commons.httpclient"/>
</or>
</not>
</and>
@@ -897,6 +915,7 @@
<optional-jar dep="swing"/>
<optional-jar dep="jsch"/>
<optional-jar dep="jdepend"/>
+ <optional-jar dep="commons.httpclient"/>
<jar destfile="${build.lib}/${optional.jars.prefix}-weblogic.jar"
basedir="${build.classes}"
@@ -1471,6 +1490,7 @@
<sysproperty key="ant.home" value="${ant.home}"/>
<sysproperty key="build.tests" file="${build.tests}"/>
+ <sysproperty key="offline" value="${offline}"/>
<sysproperty key="build.tests.value" value="${build.tests.value}"/>
<sysproperty key="tests-classpath.value"
value="${tests-classpath.value}"/>
@@ -1624,6 +1644,7 @@
<sysproperty key="ant.home" value="${ant.home}"/>
<sysproperty key="build.tests" file="${build.tests}"/>
<sysproperty key="build.tests.value" value="${build.tests.value}"/>
+ <sysproperty key="offline" value="${offline}"/>
<sysproperty key="tests-classpath.value"
value="${tests-classpath.value}"/>
<classpath refid="tests-classpath"/>
1.676 +2 -0 ant/WHATSNEW
Index: WHATSNEW
===================================================================
RCS file: /home/cvs/ant/WHATSNEW,v
retrieving revision 1.675
retrieving revision 1.676
diff -u -r1.675 -r1.676
--- WHATSNEW 21 Oct 2004 13:54:25 -0000 1.675
+++ WHATSNEW 25 Oct 2004 23:13:39 -0000 1.676
@@ -68,6 +68,8 @@
* Added a new "failall" value for the onerror attribute of <typedef>.
Bugzilla report 31685.
+* New task <getlibraries> can retrieve library files from a maven repository.
+
Changes from Ant 1.6.2 to current Ant 1.6 CVS version
=====================================================
1.1 ant/src/etc/testcases/taskdefs/optional/getlibraries.xml
Index: getlibraries.xml
===================================================================
<?xml version="1.0"?>
<project name="getlibraries" basedir="." default="all">
<!-- use the normal one at ibiblio-->
<mavenrepository id="maven"/>
<target name="init">
<property name="lib.dir" value="getlib"/>
<mkdir dir="${lib.dir}"/>
<property name="commons.logging" value="commons-logging-1.0.1.jar"/>
<presetdef name="getlib">
<getlibraries destDir="${lib.dir}">
<library archive="commons-logging" project="commons-logging" version="1.0.1"/>
</getlibraries>
</presetdef>
<macrodef name="assert-downloaded">
<attribute name="library" default="${commons.logging}"/>
<sequential>
<available property="@{library}.exists"
file="${lib.dir}/@{library}"/>
<fail unless="@{library}.exists">
Not found: ${lib.dir}@{library}
</fail>
</sequential>
</macrodef>
</target>
<target name="cleanup">
<delete dir="${lib.dir}"/>
</target>
<target name="testEmpty" depends="init">
<getlibraries/>
</target>
<target name="testEmpty2" depends="init">
<getlibraries destDir="${lib.dir}">
</getlibraries>
</target>
<target name="testEmpty3" depends="init">
<getlibraries destDir="${lib.dir}">
<repository/>
</getlibraries>
</target>
<target name="testNoRepo" depends="init">
<getlib/>
</target>
<target name="testUnknownReference" depends="init">
<getlib>
<repository refid="unknown"/>
</getlib>
</target>
<target name="testFunctionalInline" depends="init">
<getlib repositoryref="maven">
</getlib>
<assert-downloaded/>
</target>
<target name="testMavenInline" depends="init">
<getlib>
<mavenrepository/>
</getlib>
<assert-downloaded/>
</target>
<target name="testTwoRepositories" depends="init">
<getlib>
<mavenrepository/>
<mavenrepository/>
</getlib>
</target>
<target name="testMavenInlineBadURL" depends="init">
<getlib>
</getlib>
</target>
<target name="testRenaming" depends="init">
<getlib>
<mavenrepository/>
<library archive="commons-logging" project="commons-logging" version="1.0.1"
destinationName="renamed.jar"
/>
</getlib>
<assert-downloaded/>
<assert-downloaded library="renamed.jar"/>
</target>
<target name="testOverwrite" depends="init">
<getlib>
<mavenrepository/>
</getlib>
<assert-downloaded/>
<getlib>
<mavenrepository/>
</getlib>
</target>
</project>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org