mbenson     2005/02/25 15:15:16

  Modified:    src/main/org/apache/tools/ant/taskdefs Tag: ANT_16_BRANCH
                        Get.java
               .        Tag: ANT_16_BRANCH WHATSNEW
               src/etc/testcases/taskdefs Tag: ANT_16_BRANCH get.xml
               src/testcases/org/apache/tools/ant/taskdefs Tag:
                        ANT_16_BRANCH GetTest.java
  Log:
  Sync Get to HEAD (hope that's okay Steve);
  in particular sync usetimestamp fix on Java 1.2
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.38.2.5  +262 -151  ant/src/main/org/apache/tools/ant/taskdefs/Get.java
  
  Index: Get.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Get.java,v
  retrieving revision 1.38.2.4
  retrieving revision 1.38.2.5
  diff -u -r1.38.2.4 -r1.38.2.5
  --- Get.java  9 Mar 2004 17:01:33 -0000       1.38.2.4
  +++ Get.java  25 Feb 2005 23:15:15 -0000      1.38.2.5
  @@ -1,5 +1,5 @@
   /*
  - * Copyright  2000-2004 The Apache Software Foundation
  + * Copyright  2000-2005 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.
  @@ -17,19 +17,21 @@
   
   package org.apache.tools.ant.taskdefs;
   
  +import org.apache.tools.ant.BuildException;
  +import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.Task;
  +import org.apache.tools.ant.util.FileUtils;
  +import org.apache.tools.ant.util.JavaEnvUtils;
  +
   import java.io.File;
   import java.io.FileOutputStream;
   import java.io.IOException;
   import java.io.InputStream;
  +import java.io.PrintStream;
   import java.net.HttpURLConnection;
   import java.net.URL;
   import java.net.URLConnection;
   import java.util.Date;
  -import org.apache.tools.ant.BuildException;
  -import org.apache.tools.ant.Project;
  -import org.apache.tools.ant.Task;
  -import org.apache.tools.ant.util.FileUtils;
  -import org.apache.tools.ant.util.JavaEnvUtils;
   
   /**
    * Gets a particular file from a URL source.
  @@ -37,12 +39,14 @@
    * actions on failures. NB: access through a firewall only works if the whole
    * Java runtime is correctly configured.
    *
  - *
    * @since Ant 1.1
    *
    * @ant.task category="network"
    */
   public class Get extends Task {
  +
  +    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
  +
       private URL source; // required
       private File dest; // required
       private boolean verbose = false;
  @@ -52,12 +56,47 @@
       private String pword = null;
   
   
  +
       /**
        * Does the work.
        *
        * @exception BuildException Thrown in unrecoverable error.
        */
       public void execute() throws BuildException {
  +
  +        //set up logging
  +        int logLevel = Project.MSG_INFO;
  +        DownloadProgress progress = null;
  +        if (verbose) {
  +            progress = new VerboseProgress(System.out);
  +        }
  +
  +        //execute the get
  +        try {
  +            doGet(logLevel, progress);
  +        } catch (IOException ioe) {
  +            log("Error getting " + source + " to " + dest);
  +            if (!ignoreErrors) {
  +                throw new BuildException(ioe, getLocation());
  +            }
  +        }
  +    }
  +
  +    /**
  +     * make a get request, with the supplied progress and logging info.
  +     * All the other config parameters are set at the task level,
  +     * source, dest, ignoreErrors, etc.
  +     * @param logLevel level to log at, see [EMAIL PROTECTED] 
Project#log(String, int)}
  +     * @param progress progress callback; null for no-callbacks
  +     * @return true for a successful download, false otherwise.
  +     * The return value is only relevant when [EMAIL PROTECTED] 
#ignoreErrors} is true, as
  +     * when false all failures raise BuildExceptions.
  +     * @throws IOException for network trouble
  +     * @throws BuildException for argument errors, or other trouble when 
ignoreErrors
  +     * is false.
  +     */
  +    public boolean doGet(int logLevel, DownloadProgress progress)
  +            throws IOException {
           if (source == null) {
               throw new BuildException("src attribute is required", 
getLocation());
           }
  @@ -68,172 +107,161 @@
   
           if (dest.exists() && dest.isDirectory()) {
               throw new BuildException("The specified destination is a 
directory",
  -                                     getLocation());
  +                    getLocation());
           }
   
           if (dest.exists() && !dest.canWrite()) {
               throw new BuildException("Can't write to " + 
dest.getAbsolutePath(),
  -                                     getLocation());
  +                    getLocation());
           }
  +        //dont do any progress, unless asked
  +        if (progress == null) {
  +            progress = new NullProgress();
  +        }
  +        log("Getting: " + source, logLevel);
  +        log("To: " + dest.getAbsolutePath(), logLevel);
   
  -        try {
  -
  -            log("Getting: " + source);
  -
  -            //set the timestamp to the file date.
  -            long timestamp = 0;
  -
  -            boolean hasTimestamp = false;
  -            if (useTimestamp && dest.exists()) {
  -                timestamp = dest.lastModified();
  -                if (verbose) {
  -                    Date t = new Date(timestamp);
  -                    log("local file date : " + t.toString());
  -                }
  +        //set the timestamp to the file date.
  +        long timestamp = 0;
   
  -                hasTimestamp = true;
  +        boolean hasTimestamp = false;
  +        if (useTimestamp && dest.exists()) {
  +            timestamp = dest.lastModified();
  +            if (verbose) {
  +                Date t = new Date(timestamp);
  +                log("local file date : " + t.toString(), logLevel);
               }
  +            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);
  -            }
  -            // prepare Java 1.1 style credentials
  -            if (uname != null || pword != null) {
  -                String up = uname + ":" + pword;
  -                String encoding;
  -                // check to see if sun's Base64 encoder is available.
  -                try {
  -                    Object encoder =
  -                            
Class.forName("sun.misc.BASE64Encoder").newInstance();
  -                    encoding = (String)
  -                            encoder.getClass().getMethod("encode", new 
Class[] {byte[].class})
  -                            .invoke(encoder, new Object[] {up.getBytes()});
  -
  -                } catch (Exception ex) { // sun's base64 encoder isn't 
available
  -                    Base64Converter encoder = new Base64Converter();
  -                    encoding = encoder.encode(up.getBytes());
  -                }
  -                connection.setRequestProperty ("Authorization",
  -                                               "Basic " + encoding);
  -            }
  +        //set up the URL connection
  +        URLConnection connection = source.openConnection();
  +        //modify the headers
  +        //NB: things like user authentication could go in here too.
  +        if (hasTimestamp) {
  +            connection.setIfModifiedSince(timestamp);
  +        }
  +        // prepare Java 1.1 style credentials
  +        if (uname != null || pword != null) {
  +            String up = uname + ":" + pword;
  +            String encoding;
  +            //we do not use the sun impl for portability,
  +            //and always use our own implementation for consistent
  +            //testing
  +            Base64Converter encoder = new Base64Converter();
  +            encoding = encoder.encode(up.getBytes());
  +            connection.setRequestProperty ("Authorization",
  +                    "Basic " + encoding);
  +        }
   
  -            //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
  +        //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
  -                    //didn't
  -                    log("Not modified - so not downloaded");
  -                    return;
  -                }
  -                // test for 401 result (HTTP only)
  -                if (httpConnection.getResponseCode()
  +            if (httpConnection.getResponseCode()
  +                    == HttpURLConnection.HTTP_NOT_MODIFIED
  +                //workaround:  doesn't work on 1.2
  +                || (hasTimestamp
  +                && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)
  +                && timestamp > httpConnection.getLastModified())) {
  +                //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
  +                //didn't
  +                log("Not modified - so not downloaded", logLevel);
  +                return false;
  +                // also, if timestamp is roughly >= now, HTTP_NOT_MODIFIED 
is _not_
  +                // returned... We may want to remove the 1.2 qualifier above.
  +            }
  +            // test for 401 result (HTTP only)
  +            if (httpConnection.getResponseCode()
                       == HttpURLConnection.HTTP_UNAUTHORIZED)  {
  -                    String message = "HTTP Authorization failure";
  -                    if (ignoreErrors) {
  -                        log(message, Project.MSG_WARN);
  -                        return;
  -                    } else {
  -                        throw new BuildException(message);
  -                    }
  +                String message = "HTTP Authorization failure";
  +                if (ignoreErrors) {
  +                    log(message, logLevel);
  +                    return false;
  +                } else {
  +                    throw new BuildException(message);
                   }
  -
               }
   
  -            //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) don't include dates, of
  -            //course.
  -
  -            InputStream is = null;
  -            for (int i = 0; i < 3; i++) {
  -                try {
  -                    is = connection.getInputStream();
  -                    break;
  -                } catch (IOException ex) {
  -                    log("Error opening connection " + ex);
  -                }
  +        }
  +
  +        //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) don't include dates, of
  +        //course.
  +
  +        InputStream is = null;
  +        for (int i = 0; i < 3; i++) {
  +            //this three attempt trick is to get round quirks in different
  +            //Java implementations. Some of them take a few goes to bind
  +            //property; we ignore the first couple of such failures.
  +            try {
  +                is = connection.getInputStream();
  +                break;
  +            } catch (IOException ex) {
  +                log("Error opening connection " + ex, logLevel);
               }
  -            if (is == null) {
  -                log("Can't get " + source + " to " + dest);
  -                if (ignoreErrors) {
  -                    return;
  -                }
  -                throw new BuildException("Can't get " + source + " to " + 
dest,
  -                                         getLocation());
  +        }
  +        if (is == null) {
  +            log("Can't get " + source + " to " + dest, logLevel);
  +            if (ignoreErrors) {
  +                return false;
               }
  +            throw new BuildException("Can't get " + source + " to " + dest,
  +                    getLocation());
  +        }
   
  -            FileOutputStream fos = new FileOutputStream(dest);
  -            boolean finished = false;
  -            try {
  -                byte[] buffer = new byte[100 * 1024];
  -                int length;
  -                int dots = 0;
  -
  -                while ((length = is.read(buffer)) >= 0) {
  -                    fos.write(buffer, 0, length);
  -                    if (verbose) {
  -                        System.out.print(".");
  -                        if (dots++ > 50) {
  -                            System.out.flush();
  -                            dots = 0;
  -                        }
  -                    }
  -                }
  -                if (verbose) {
  -                    System.out.println();
  -                }
  -                finished = true;
  -            } finally {
  -                if (fos != null) {
  -                    fos.close();
  -                }
  -                is.close();
  -                // we have started to (over)write dest, but failed.
  -                // Try to delete the garbage we'd otherwise leave
  -                // behind.
  -                if (!finished) {
  -                    dest.delete();
  -                }
  +        FileOutputStream fos = new FileOutputStream(dest);
  +        progress.beginDownload();
  +        boolean finished = false;
  +        try {
  +            byte[] buffer = new byte[100 * 1024];
  +            int length;
  +            while ((length = is.read(buffer)) >= 0) {
  +                fos.write(buffer, 0, length);
  +                progress.onTick();
  +            }
  +            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) {
  +                dest.delete();
               }
  +        }
  +        progress.endDownload();
   
  -            //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()
  +        //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) {
  -                    FileUtils.newFileUtils()
  -                        .setFileLastModified(dest, remoteTimestamp);
  -                }
  +                        ? " - using current time instead"
  +                        : ""), logLevel);
               }
  -        } catch (IOException ioe) {
  -            log("Error getting " + source + " to " + dest);
  -            if (ignoreErrors) {
  -                return;
  +            if (remoteTimestamp != 0) {
  +                FILE_UTILS.setFileLastModified(dest, remoteTimestamp);
               }
  -            throw new BuildException(ioe, getLocation());
           }
  +
  +        //successful download
  +        return true;
       }
   
  +
       /**
        * Set the URL to get.
        *
  @@ -289,9 +317,7 @@
        * @param v "true" to enable file time fetching
        */
       public void setUseTimestamp(boolean v) {
  -        if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
  -            useTimestamp = v;
  -        }
  +        useTimestamp = v;
       }
   
   
  @@ -320,7 +346,7 @@
       *
       *********************************************************************/
   
  -    private static class  Base64Converter {
  +    protected static class  Base64Converter {
   
           public final char [ ]  alphabet = {
               'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',   //  0 to  7
  @@ -391,4 +417,89 @@
               return new String(out);
           }
        }
  +
  +    public interface DownloadProgress {
  +        /**
  +         * begin a download
  +         */
  +        public void beginDownload();
  +
  +        /**
  +         * tick handler
  +         *
  +         */
  +        public void onTick();
  +
  +        /**
  +         * end a download
  +         */
  +        public void endDownload();
  +    }
  +
  +    /**
  +     * do nothing with progress info
  +     */
  +    public static class NullProgress implements DownloadProgress {
  +
  +        /**
  +         * begin a download
  +         */
  +        public void beginDownload() {
  +
  +        }
  +
  +        /**
  +         * tick handler
  +         *
  +         */
  +        public void onTick() {
  +        }
  +
  +        /**
  +         * end a download
  +         */
  +        public void endDownload() {
  +
  +        }
  +    }
  +
  +    /**
  +     * verbose progress system prints to some output stream
  +     */
  +    public static class VerboseProgress implements DownloadProgress  {
  +        private int dots = 0;
  +        PrintStream out;
  +
  +        public VerboseProgress(PrintStream out) {
  +            this.out = out;
  +        }
  +
  +        /**
  +         * begin a download
  +         */
  +        public void beginDownload() {
  +            dots = 0;
  +        }
  +
  +        /**
  +         * tick handler
  +         *
  +         */
  +        public void onTick() {
  +            out.print(".");
  +            if (dots++ > 50) {
  +                out.flush();
  +                dots = 0;
  +            }
  +        }
  +
  +        /**
  +         * end a download
  +         */
  +        public void endDownload() {
  +            out.println();
  +            out.flush();
  +        }
  +    }
  +
   }
  
  
  
  No                   revision
  No                   revision
  1.503.2.184 +2 -0      ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/ant/WHATSNEW,v
  retrieving revision 1.503.2.183
  retrieving revision 1.503.2.184
  diff -u -r1.503.2.183 -r1.503.2.184
  --- WHATSNEW  24 Feb 2005 20:25:57 -0000      1.503.2.183
  +++ WHATSNEW  25 Feb 2005 23:15:15 -0000      1.503.2.184
  @@ -219,6 +219,8 @@
   * <javac debug="false"> created an invalid command line when running
     the Symantec Java compiler.
   
  +* Get with usetimestamp did not work on Java 1.2.
  +
   Changes from Ant 1.6.1 to Ant 1.6.2
   ===================================
   
  
  
  
  No                   revision
  No                   revision
  1.4.6.1   +44 -0     ant/src/etc/testcases/taskdefs/get.xml
  
  Index: get.xml
  ===================================================================
  RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/get.xml,v
  retrieving revision 1.4
  retrieving revision 1.4.6.1
  diff -u -r1.4 -r1.4.6.1
  --- get.xml   8 May 2001 09:35:27 -0000       1.4
  +++ get.xml   25 Feb 2005 23:15:16 -0000      1.4.6.1
  @@ -24,6 +24,50 @@
   
     <target name="test6">
       <get src="http://www.apache.org/"; dest="get.tmp"/>
  +
  +    <fileset id="t6" file="get.tmp" />
  +    <pathconvert property="t6" refid="t6" setonempty="false" />
  +
  +    <fail message="get failed">
  +      <condition>
  +        <not>
  +          <isset property="t6" />
  +        </not>
  +      </condition>
  +    </fail>
  +  </target>
  +
  +  <target name="testUseTimestamp">
  +    <property name="pat" value="yyyyMMddHHmm" />
  +
  +    <tstamp>
  +      <format property="dt" pattern="${pat}" offset="-90" unit="second" />
  +    </tstamp>
  +
  +    <touch file="get.tmp" datetime="${dt}" pattern="${pat}" />
  +
  +    <get src="http://www.apache.org/"; dest="get.tmp"
  +         usetimestamp="true" verbose="true" />
  +
  +    <fileset id="ts" file="get.tmp">
  +      <date when="equal" datetime="${dt}" pattern="${pat}" />
  +    </fileset>
  +
  +    <pathconvert property="ts" refid="ts" setonempty="false" />
  +
  +    <fail message="get w/ timestamp should have failed.">
  +      <condition>
  +        <not>
  +          <isset property="ts" />
  +        </not>
  +      </condition>
  +    </fail>
  +  </target>
  +
  +  <target name="cleanup">
  +    <delete>
  +      <fileset dir="${basedir}" includes="get.tmp" />
  +    </delete>
     </target>
   
   </project>
  
  
  
  No                   revision
  No                   revision
  1.7.2.5   +8 -7      
ant/src/testcases/org/apache/tools/ant/taskdefs/GetTest.java
  
  Index: GetTest.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/GetTest.java,v
  retrieving revision 1.7.2.4
  retrieving revision 1.7.2.5
  diff -u -r1.7.2.4 -r1.7.2.5
  --- GetTest.java      9 Mar 2004 17:02:01 -0000       1.7.2.4
  +++ GetTest.java      25 Feb 2005 23:15:16 -0000      1.7.2.5
  @@ -1,5 +1,5 @@
   /*
  - * Copyright  2000-2001,2004 The Apache Software Foundation
  + * Copyright 2000-2001, 2004-2005 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.
  @@ -32,6 +32,10 @@
           configureProject("src/etc/testcases/taskdefs/get.xml");
       }
   
  +    public void tearDown() {
  +        executeTarget("cleanup");
  +    }
  +
       public void test1() {
           expectBuildException("test1", "required argument missing");
       }
  @@ -54,13 +58,10 @@
   
       public void test6() {
           executeTarget("test6");
  -        java.io.File f = new File(getProjectDir(), "get.tmp");
  -        if (!f.exists()) {
  -            fail("get failed");
  -        } else {
  -            f.delete();
  -        }
  +    }
   
  +    public void testUseTimestamp() {
  +        executeTarget("testUseTimestamp");
       }
   
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to