All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hfg.anttask.GetWild Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
package com.hfg.anttask;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

import com.hfg.datetime.DateSortDirection;
import com.hfg.util.StringUtil;
import com.hfg.util.io.HTTPRemoteFileLister;
import com.hfg.util.io.RemoteFile;
import com.hfg.util.io.RemoteFileLister;
import com.hfg.util.io.RemoteFileListerFactory;
import com.hfg.util.io.RemoteFileTimestampComparator;


//------------------------------------------------------------------------------
/**
  Ant task for retrieving a particular file from a wildcarded URL source.
  In the case of multiple matches, the newest is the one returned. HTTP, FTP and file system URL's are supported.
  

Normally, this task is used with files whose names contain a variable portion, the matching of which allows '*' wildcarding.

Requires the jakarta commons-net jar (for FTP).

If the task's name is set and multiple matching is not enabled, five project properties are set:
  • Property <taskname> is set to the destination file's full path.
  • Property <taskname>.name is set to the destination file's name.
  • Property <taskname>.basename is set to the destination file's name minus the last '.extenstion'.
  • Property <taskname>.baseURL is set to the URL of the source file's parent directory.
  • Property <taskname>.wildcard is set to the portion of the URL corresponding to the first '*'.

Parameters

Parameter descriptions
Attribute Description Required
name The name (handle) of the property. No
src The URL (http, ftp, or a file system path) of the remote file (may contain one or more '*' wildcards). Yes
dest The local file to copy into. Yes
destdir The local directory to copy into. The file's remote name is maintained.
matchmultiple Used with destdir, retrieves all matching files and no properties are set. If false, only the most recent matching file is retrieved and properties are set. (false by default) No
ignoreerrors Do not halt ant execution on failure. (false by default) No
usetimestamp Use the file's timestamp and size to determine if freshening the local copy is necessary. (true by default) No
if Only execute if a property of the given name exists in the current project. No
unless Only execute if a property of the given name doesn't exist in the current project. No
useragent User-Agent HTTP header to send, Ant will specify a User-Agent header of "Apache Ant VERSION" unless overridden by this attribute. No

The if and unless attributes make the execution conditional -both probe for the named property being defined. The if tests for the property being defined, the unless for a property being undefined.

If both attributes are set, then the task executes only if both tests are true. i.e.
execute := defined(ifProperty) && !defined(unlessProperty)
The following example downloads the most recent file matching the src pattern to the specified local destination:
      <getwild name='ij'
         src='http://rsb.info.nih.gov/ij/download/zips/ij*.zip'
         dest='${tmp.dir}/ij.zip' />
   
@author J. Alex Taylor, hairyfatguy.com */ //------------------------------------------------------------------------------ // com.hfg XML/HTML Coding Library // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com // [email protected] //------------------------------------------------------------------------------ // Wanted to just extend org.apache.tools.ant.taskdefs.Get but I didn't have // access to the variables. // - JAT public class GetWild extends Task { private String mName; private String mSource; // required private File mDest; private File mDestDir; private boolean mUseTimestamp = true; //on by default private boolean mIgnoreErrors = false; private boolean mMatchMultiple = false; private String mIfCondition; private String mUnlessCondition; private String mUserAgentString; //--------------------------------------------------------------------------- /** * Set the task's name. * * @param name name for the task */ public void setName(String name) { this.mName = name; } //--------------------------------------------------------------------------- /** * The remote file for retrieval. * @param inURL the remote file for retrieval */ public void setSrc(String inURL) { this.mSource = inURL; } //--------------------------------------------------------------------------- /** * Specifies where to copy the source file. * @param inValue the local file to copy the remote file to */ public void setDest(File inValue) { this.mDest = inValue; } //--------------------------------------------------------------------------- /** * Specifies the local directory to copy the remote file into * (preserving the file's remote name). * @param inValue the local directory to copy the remote file into */ public void setDestdir(File inValue) { this.mDestDir = inValue; } //--------------------------------------------------------------------------- /** * Only execute if a property of the given name exists in the current project. * @param inPropertyName property name */ public void setIf(String inPropertyName) { mIfCondition = inPropertyName; } //--------------------------------------------------------------------------- /** * Only execute if a property of the given name does not exist in the current project. * @param inPropertyName property name */ public void setUnless(String inPropertyName) { mUnlessCondition = inPropertyName; } //--------------------------------------------------------------------------- /** * Specifies whether or not to retrieve multiple matching files. * @param inValue whether or not to retrieve multiple matching files */ public void setMatchMultiple(boolean inValue) { mMatchMultiple = inValue; } //--------------------------------------------------------------------------- /** * Specifies whether or not to ignore retrieval errors. * @param inValue whether or not to ignore retrieval errors */ public void setIgnoreErrors(boolean inValue) { mIgnoreErrors = inValue; } //--------------------------------------------------------------------------- /** * If set to true, the remote file's timestamp will be compared * to the local file (if present) before downloading. * @param inValue whether or not to compare the remote timestamp to the local file */ public void setUseTimestamp(boolean inValue) { mUseTimestamp = inValue; } //--------------------------------------------------------------------------- /** * User-Agent HTTP header to send, Ant will specify a User-Agent header of "Apache Ant VERSION" unless overridden by this attribute. * @param inValue the value to use for the User-Agent header field in HTTP requests */ public void setUserAgent(String inValue) { mUserAgentString = inValue; } //--------------------------------------------------------------------------- /** * Does the work. * * @exception BuildException Thrown in unrecoverable error. */ public void execute() throws BuildException { if (TaskUtil.testIfCondition(mIfCondition, getProject()) && TaskUtil.testUnlessCondition(mUnlessCondition, getProject())) { if (mSource == null) { throw new BuildException("'src' attribute is required", getLocation()); } if (mSource.startsWith("http")) { String antVersionString = getProject().getProperty("ant.version"); mUserAgentString = "Apache Ant" + (StringUtil.isSet(antVersionString) ? " " + antVersionString : ""); } List remoteFiles = getRemoteFiles(); File destination = getDestination(); if (mMatchMultiple) { if (null == mDestDir) { throw new BuildException("'destdir' attribute is required when matchmultiple is true", getLocation()); } Iterator iter = remoteFiles.iterator(); while (iter.hasNext()) { RemoteFile remoteFile = (RemoteFile) iter.next(); retrieveRemoteFile(remoteFile, destination); } } else { retrieveRemoteFile((RemoteFile) remoteFiles.get(0), destination); } } } //--------------------------------------------------------------------------- private File getDestination() { File destination = null; if (mDest == null && mDestDir == null) { throw new BuildException("Either a 'dest' or 'destdir' attribute is required", getLocation()); } if (mDest != null) { if (mDest.exists() && mDest.isDirectory()) { throw new BuildException("The specified destination is a directory", getLocation()); } if (mDest.exists() && !mDest.canWrite()) { throw new BuildException("Can't write to " + mDest.getAbsolutePath(), getLocation()); } destination = mDest; } else if (mDestDir != null) { if (mDestDir.exists() && !mDestDir.isDirectory()) { throw new BuildException("The specified destdir is not a directory", getLocation()); } if (!mDestDir.exists()) { mDestDir.mkdirs(); } destination = mDestDir; } return destination; } //--------------------------------------------------------------------------- private List getRemoteFiles() { RemoteFileLister lister = RemoteFileListerFactory.getRemoteFileLister(mSource); if (lister instanceof HTTPRemoteFileLister) { ((HTTPRemoteFileLister) lister).setUserAgentString(mUserAgentString); } List remoteFiles = lister.getUnfilteredRemoteFileList(); if (0 == remoteFiles.size()) { throw new BuildException( "No file found matching '" + mSource + "'"); } Collections.sort(remoteFiles, new RemoteFileTimestampComparator(DateSortDirection.NEWER_TO_OLDER)); return remoteFiles; } //--------------------------------------------------------------------------- private void retrieveRemoteFile(RemoteFile inRemoteFile, File inLocalDest) { log("Getting: " + inRemoteFile.getPath()); Calendar timestamp = inRemoteFile.getTimestamp(); // Makes a HEAD request and will update the url for redirections File destFile; if (inLocalDest.isDirectory()) { destFile = new File(inLocalDest, inRemoteFile.getName()); } else { destFile = inLocalDest; } log("Local File: " + destFile); if (mUseTimestamp && timestamp != null && destFile.exists() && inRemoteFile.getTimestamp().getTimeInMillis() <= destFile.lastModified() && inRemoteFile.getSize() == destFile.length()) { // Already up-to-date. log("Already up-to-date"); } else { try { inRemoteFile.writeToLocalFile(destFile); } catch (IOException e) { log("Error getting " + mSource + " to " + destFile + ": " + e.toString()); if (!mIgnoreErrors) throw new BuildException(e, getLocation()); } } if (mName != null && !mMatchMultiple) { setProjectProperties(inRemoteFile, destFile); } } //--------------------------------------------------------------------------- private void setProjectProperties(RemoteFile inRemoteFile, File inDestinationFile) { getProject().setProperty(mName, inDestinationFile.getPath()); getProject().setProperty(mName + ".name", inDestinationFile.getName()); int dotIndex = inDestinationFile.getName().lastIndexOf("."); String basename = (dotIndex > 0 ? inDestinationFile.getName().substring(0, dotIndex) : inDestinationFile.getName()); getProject().setProperty(mName + ".basename", basename); int slashIndex = inRemoteFile.getPath().lastIndexOf("/"); if (slashIndex >= 0) { getProject().setProperty(mName + ".baseURL", inRemoteFile.getURL().substring(0, slashIndex)); } int wildcardIndex = mSource.indexOf("*"); if (wildcardIndex > 0) { int prevSlash = mSource.lastIndexOf("/", wildcardIndex); int postSlash = mSource.indexOf("/", wildcardIndex); if (postSlash < 0) { postSlash = mSource.length(); } Matcher m = Pattern.compile(mSource.substring(prevSlash, wildcardIndex) + "(.+)" + mSource.substring(wildcardIndex + 1, postSlash)).matcher(inRemoteFile.getURL()); if (m.find()) { getProject().setProperty(mName + ".wildcard", m.group(1)); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy