You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bo...@locus.apache.org on 2000/07/24 15:23:34 UTC

cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs Expand.java Get.java Touch.java Untar.java

bodewig     00/07/24 06:23:33

  Modified:    src/main/org/apache/tools/ant BuildException.java
               src/main/org/apache/tools/ant/taskdefs Expand.java Get.java
                        Touch.java Untar.java
  Log:
  Added usetimestamp attribute to Get so that it only downloads a file
  via HTTP if the source is newer than the local file.
  Submitted by:	Steve Loughran <st...@iseran.com>
  
  Revision  Changes    Path
  1.7       +12 -0     jakarta-ant/src/main/org/apache/tools/ant/BuildException.java
  
  Index: BuildException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/BuildException.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- BuildException.java	2000/07/11 11:14:46	1.6
  +++ BuildException.java	2000/07/24 13:23:25	1.7
  @@ -133,6 +133,18 @@
       }
   
       /**
  +     * Constructs an exception with the given exception as
  +     * a root cause and a location in a file.
  +     * @param cause Exception that might have cause this one.
  +     * @param location Location in the project file where the error occured.
  +     */
  +
  +    public BuildException(Throwable cause, Location location) {
  +        this(cause);
  +	this.location = location;
  +    }
  +
  +    /**
        * Returns the nested exception.
        */
       public Throwable getException() {
  
  
  
  1.9       +4 -2      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Expand.java
  
  Index: Expand.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Expand.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Expand.java	2000/07/12 13:30:48	1.8
  +++ Expand.java	2000/07/24 13:23:28	1.9
  @@ -61,7 +61,7 @@
    * Unzip a file. 
    *
    * @author costin@dnt.ro
  - * @author Stefan Bodewig <a href="mailto:stefan.bodewig@megabit.net">stefan.bodewig@megabit.net</a>
  + * @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
    */
   public class Expand extends Task {
       private String dest; // req
  @@ -81,6 +81,8 @@
   
           Touch touch = (Touch) project.createTask("touch");
           touch.setOwningTarget(target);
  +        touch.setTaskName(getTaskName());
  +        touch.setLocation(getLocation());
           
           File srcF=project.resolveFile(source);
           File dir=project.resolveFile(dest);
  @@ -116,7 +118,7 @@
   		    }
   
                       if (project.getJavaVersion() != Project.JAVA_1_1) {
  -                        touch.setFile(f.getAbsolutePath());
  +                        touch.setFile(f);
                           touch.setMillis(ze.getTime());
                           touch.touch();
                       }
  
  
  
  1.5       +136 -28   jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Get.java
  
  Index: Get.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Get.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Get.java	2000/07/06 16:48:15	1.4
  +++ Get.java	2000/07/24 13:23:29	1.5
  @@ -57,40 +57,79 @@
   import org.apache.tools.ant.*;
   import java.io.*;
   import java.net.*;
  +import java.util.*;
  +
   /**
  - * Get a particular source. 
  + * Get a particular file from a URL source. 
  + * Options include verbose reporting, timestamp based fetches and controlling 
  + * actions on failures. NB: access through a firewall only works if the whole 
  + * Java runtime is correctly configured.
    *
    * @author costin@dnt.ro
    */
   public class Get extends Task {
  -    private String source; // required
  -    private String dest; // required
  -    private String verbose = "";
  -    String ignoreErrors=null;
  +    private URL source; // required
  +    private File dest; // required
  +    private boolean verbose = false;
  +    private boolean useTimestamp = false; //off by default
  +    private boolean ignoreErrors = false;
       
       /**
        * Does the work.
        *
  -     * @exception BuildException Thrown in unrecovrable error.
  +     * @exception BuildException Thrown in unrecoverable error.
        */
       public void execute() throws BuildException {
   	try {
  -            URL url = null;
  -            try {
  -                url = new URL(source);
  -            } catch (MalformedURLException e) {
  -                throw new BuildException(e.toString());
  -            }
   
   	    log("Getting: " + source);
  +
  +	    	//set the timestamp to the file date.
  +	    long timestamp=0;
   
  -	    File destF=new File(dest);
  -	    FileOutputStream fos = new FileOutputStream(destF);
  +            boolean hasTimestamp=false;
  +	    if(useTimestamp && dest.exists()) {
  +	        timestamp=dest.lastModified();
  +                if (verbose)  {
  +                    Date t=new Date(timestamp);
  +                    log("local file date : "+t.toString());
  +                }
  +                
  +                hasTimestamp=true;
  +            }
  +	
  +            //set up the URL connection
  +            URLConnection connection=source.openConnection();
  +            //modify the headers
  +            //NB: things like user authentication could go in here too.
  +            if(useTimestamp && hasTimestamp) {
  +                connection.setIfModifiedSince(timestamp);
  +            }
   
  +            //connect to the remote site (may take some time)
  +            connection.connect();
  +            //next test for a 304 result (HTTP only)
  +            if(connection instanceof HttpURLConnection)  {
  +           	HttpURLConnection httpConnection=(HttpURLConnection)connection;
  +                if(httpConnection.getResponseCode()==HttpURLConnection.HTTP_NOT_MODIFIED)  {
  +                    //not modified so no file download. just return instead
  +                    //and trace out something so the user doesn't think that the 
  +                    //download happened when it didnt
  +                    log("Not modified - so not downloaded");
  +                    return; 
  +                }
  +            }
  +
  +            //REVISIT: at this point even non HTTP connections may support the if-modified-since
  +            //behaviour -we just check the date of the content and skip the write if it is not
  +            //newer. Some protocols (FTP) dont include dates, of course. 
  +           	
  +	    FileOutputStream fos = new FileOutputStream(dest);
  +
   	    InputStream is=null;
   	    for( int i=0; i< 3 ; i++ ) {
   		try {
  -		    is = url.openStream();
  +		    is = connection.getInputStream();
   		    break;
   		} catch( IOException ex ) {
   		    log( "Error opening connection " + ex );
  @@ -98,8 +137,10 @@
   	    }
   	    if( is==null ) {
   		log( "Can't get " + source + " to " + dest);
  -		if( ignoreErrors != null ) return;
  -		throw new BuildException( "Can't get " + source + " to " + dest);
  +		if(ignoreErrors) 
  +                    return;
  +		throw new BuildException( "Can't get " + source + " to " + dest,
  +                                          location);
   	    }
   		
   	    byte[] buffer = new byte[100 * 1024];
  @@ -107,25 +148,70 @@
   	    
   	    while ((length = is.read(buffer)) >= 0) {
   		fos.write(buffer, 0, length);
  -		if ("true".equals(verbose)) System.out.print(".");
  +		if (verbose) System.out.print(".");
   	    }
  -	    if( "true".equals(verbose)) System.out.println();
  +	    if(verbose) System.out.println();
   	    fos.close();
   	    is.close();
  +           
  +            //if (and only if) the use file time option is set, then the 
  +            //saved file now has its timestamp set to that of the downloaded file
  +            if(useTimestamp)  {
  +           	long remoteTimestamp=connection.getLastModified();
  +                if (verbose)  {
  +                    Date t=new Date(remoteTimestamp);
  +                    log("last modified = "+t.toString()
  +                   	+((remoteTimestamp==0)?" - using current time instead":""));
  +                }
  +                if(remoteTimestamp!=0)
  +                    touchFile(dest,remoteTimestamp);
  +            }
  +
  +           
  +
   	} catch (IOException ioe) {
   	    log("Error getting " + source + " to " + dest );
  -	    if( ignoreErrors != null ) return;
  -	    throw new BuildException(ioe.toString());
  +	    if(ignoreErrors) 
  +                return;
  +	    throw new BuildException(ioe, location);
   	}
       }
  +    
  +    /** 
  +     * set the timestamp of a named file to a specified time.
  +     *
  +     * @param filename
  +     * @param time in milliseconds since the start of the era
  +     * @return true if it succeeded. False means that this is a
  +     * java1.1 system and that file times can not be set
  +     *@exception BuildException Thrown in unrecoverable error. Likely
  +     *this comes from file access failures.
  +     */
  +    protected boolean touchFile(File file, long timemillis) 
  +        throws BuildException  {
   
  +        if (project.getJavaVersion() != Project.JAVA_1_1) {
  +            Touch touch = (Touch) project.createTask("touch");
  +            touch.setOwningTarget(target);
  +            touch.setTaskName(getTaskName());
  +            touch.setLocation(getLocation());
  +            touch.setFile(file);
  +            touch.setMillis(timemillis);
  +            touch.touch();
  +            return true;
  +            
  +        } else {
  +            return false;
  +        }
  +    }	
  +
       /**
        * Set the URL.
        *
  -     * @param d URL for the file.
  +     * @param u URL for the file.
        */
  -    public void setSrc(String d) {
  -	this.source=d;
  +    public void setSrc(URL u) {
  +	this.source = u;
       }
   
       /**
  @@ -133,7 +219,7 @@
        *
        * @param dest Path to file.
        */
  -    public void setDest(String dest) {
  +    public void setDest(File dest) {
   	this.dest = dest;
       }
   
  @@ -142,16 +228,38 @@
        *
        * @param v if "true" then be verbose
        */
  -    public void setVerbose(String v) {
  +    public void setVerbose(boolean v) {
   	verbose = v;
       }
   
       /**
        * Don't stop if get fails if set to "<CODE>true</CODE>".
        *
  -     * @param v if "true" then be verbose
  +     * @param v if "true" then don't report download errors up to ant
        */
  -    public void setIgnoreErrors(String v) {
  +    public void setIgnoreErrors(boolean v) {
   	ignoreErrors = v;
       }
  +
  +    /**
  +     * Use timestamps, if set to "<CODE>true</CODE>".
  +     *
  +     * <p>In this situation, the if-modified-since header is set so that the file is
  +     * only fetched if it is newer than the local file (or there is no local file)
  +     * This flag is only valid on HTTP connections, it is ignored in other cases.
  +     * When the flag is set, the local copy of the downloaded file will also 
  +     * have its timestamp set to the remote file time. 
  +     * <br>
  +     * Note that remote files of date 1/1/1970 (GMT) are treated as 'no timestamp', and
  +     * web servers often serve files with a timestamp in the future by replacing their timestamp
  +     * with that of the current time. Also, inter-computer clock differences can cause no end of 
  +     * grief. 
  +     * @param v "true" to enable file time fetching
  +     */
  +    public void setUseTimestamp(boolean v) {
  +        if (project.getJavaVersion() != Project.JAVA_1_1) {
  +            useTimestamp = v;
  +        }
  +    }
  +
   }
  
  
  
  1.4       +3 -3      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Touch.java
  
  Index: Touch.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Touch.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Touch.java	2000/07/06 16:48:19	1.3
  +++ Touch.java	2000/07/24 13:23:30	1.4
  @@ -73,7 +73,7 @@
    * created. Setting the modification time of files is not supported in
    * JDK 1.1.
    *
  - * @author Stefan Bodewig <a href="mailto:stefan.bodewig@megabit.net">stefan.bodewig@megabit.net</a> 
  + * @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a> 
    */
   public class Touch extends Task {
   
  @@ -87,8 +87,8 @@
       /**
        * The name of the file to touch.
        */
  -    public void setFile(String name) {
  -        file = project.resolveFile(name);
  +    public void setFile(File file) {
  +        this.file = file;
       }
   
       /**
  
  
  
  1.8       +4 -2      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Untar.java
  
  Index: Untar.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Untar.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Untar.java	2000/07/10 11:04:22	1.7
  +++ Untar.java	2000/07/24 13:23:30	1.8
  @@ -63,7 +63,7 @@
    *
    * Heavily based on the Expand task.
    *
  - * @author Stefan Bodewig <a href="mailto:stefan.bodewig@megabit.net">stefan.bodewig@megabit.net</a>
  + * @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
    */
   public class Untar extends Task {
       private String dest; // req
  @@ -78,6 +78,8 @@
   
           Touch touch = (Touch) project.createTask("touch");
           touch.setOwningTarget(target);
  +        touch.setTaskName(getTaskName());
  +        touch.setLocation(getLocation());
                       
           File srcF=project.resolveFile(source);
   
  @@ -123,7 +125,7 @@
                       }
   
                       if (project.getJavaVersion() != Project.JAVA_1_1) {
  -                        touch.setFile(f.getAbsolutePath());
  +                        touch.setFile(f);
                           touch.setMillis(te.getModTime().getTime());
                           touch.touch();
                       }