- new generic close method - reduces duplicate code (may be useful for when we can finally remove code -> Ant2?)
- minor loop tweak
- buffer compare for JDK1.4+ (only runs on files < 1Mb to conserve memory during builds)


+ int stackSize = s.size();
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (".".equals(thisToken)) {
continue;
} else if ("..".equals(thisToken)) {
- if (s.size() < 2) {
- throw new BuildException("Cannot resolve path " + orig);
- } else {
+ if (stackSize > 2) {
s.pop();
+ } else {
+ throw new BuildException("Cannot resolve path " + orig);
}



here s.pop() is going to change s.size(), but you don't update
stackSize.


Yes, I'm sorry - I looked over the code again and actually storing and then manually updating was nowhere near as maintainable.



+ /* If we have Java => 1.4, we can use NIO
+ * This buffer comparison simply maps the entire file into memory,
+ * it's not concerned with memory usage - for large files this
+ * may cause problems + */
+ if (JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_4)
+ ||JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_5)
+ ) {



If you want to assert JDK 1.4+, you better reverse the logic for forwards compatibility reasons. I.e. check that we currently are not running on JDK 1.2 or 1.3 (less than 1.2 is not possible anymore).



Ok done in attached patch. I also check for 1.0 and 1.2 (just in case) and the check also includes filesize too (< 1Mb).

Going to hack my way through all the horrible MSVSS* code now for style - Eclipse is throwing a fit over variable names :(
As an aside, I went through the entire codebase last night and replaced every
try {
somthing.close()
} catch (IOException e) {
//swallow exception
}


with FileUtils.close()

These were done against a slightly older sourcebase as I don't have net access at home and have to lug my laptop down the road. If you're interested I'll post the patch tonight, but it affects a lot of classes (~50+) and I can imagine it being a nightmare to be certain of everything still being ok afterwards (although the test cases help with that).

Kev
Index: FileUtils.java
===================================================================
RCS file: 
/home/cvspublic/ant/src/main/org/apache/tools/ant/util/FileUtils.java,v
retrieving revision 1.79
diff -u -r1.79 FileUtils.java
--- FileUtils.java      15 Dec 2004 12:10:43 -0000      1.79
+++ FileUtils.java      16 Dec 2004 03:45:43 -0000
@@ -22,18 +22,22 @@
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
 import java.io.OutputStreamWriter;
+import java.io.RandomAccessFile;
 import java.io.Reader;
 import java.io.Writer;
-import java.io.OutputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 import java.text.CharacterIterator;
 import java.text.DecimalFormat;
 import java.text.StringCharacterIterator;
@@ -41,12 +45,13 @@
 import java.util.Stack;
 import java.util.StringTokenizer;
 import java.util.Vector;
+
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.launch.Locator;
 import org.apache.tools.ant.taskdefs.condition.Os;
 import org.apache.tools.ant.types.FilterSetCollection;
-import org.apache.tools.ant.launch.Locator;
 
 /**
  * This class also encapsulates methods which allow Files to be
@@ -78,7 +83,9 @@
      * the granularity of timestamps under Unix
      */
     public static final long UNIX_FILE_TIMESTAMP_GRANULARITY = 1000;
-
+    
+    // in bytes (max size 1Mb) beware of trailing 'l' != 1
+    private static final long MAX_FILE_SIZE = 1024*1024*1l; 
 
     // stolen from FilePathToURI of the Xerces-J team
     static {
@@ -824,10 +831,10 @@
             if (".".equals(thisToken)) {
                 continue;
             } else if ("..".equals(thisToken)) {
-                if (s.size() < 2) {
-                    throw new BuildException("Cannot resolve path " + orig);
+                if (s.size() > 2) {
+                       s.pop();
                 } else {
-                    s.pop();
+                       throw new BuildException("Cannot resolve path " + orig);
                 }
             } else { // plain component
                 s.push(thisToken);
@@ -835,7 +842,7 @@
         }
 
         StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < s.size(); i++) {
+        for (int i = 0, size = s.size(); i < size; i++) {
             if (i > 1) {
                 // not before the filesystem root and not after it, since root
                 // already contains one
@@ -843,8 +850,6 @@
             }
             sb.append(s.elementAt(i));
         }
-
-
         path = sb.toString();
         if (dosWithDrive) {
             path = path.replace('/', '\\');
@@ -993,7 +998,18 @@
             // different size =>false
             return false;
         }
-
+        /* If we have Java => 1.4, we can use NIO
+         * This buffer comparison simply maps the entire file into memory,
+         * if files are over 1Mb (defined in MAX_FILE_SIZE), then
+         * don't use NIO, takes up too much memory
+         */
+        if ((!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_2))
+                       && 
(!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_3))
+                               && 
(!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_1))
+                               && 
(!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_0))
+                               && (f1.length() < MAX_FILE_SIZE)) {
+               return bufferEquals(f1, f2);
+        }
         InputStream in1 = null;
         InputStream in2 = null;
         try {
@@ -1016,6 +1032,36 @@
             close(in2);
         }
     }
+    
+        /**
+            * Uses java.nio packages to compare the contents of two files.
+            * Each file is read into memory and a byte buffer is created.
+            * As soon as a byte is different the method returns.
+            * @param f1 the first file to compare
+            * @param f2 the file to compare with
+            * @return true if files are identical, false otherwise
+            * @throws FileNotFoundException
+            * @throws IOException
+            */
+           private boolean bufferEquals(File f1, File f2) throws 
FileNotFoundException, IOException {
+               FileChannel compareeChannel = new RandomAccessFile(f1, 
"r").getChannel();
+               FileChannel comparerChannel = new RandomAccessFile(f2, 
"r").getChannel();
+               
+               ByteBuffer compareeBuf = 
compareeChannel.map(FileChannel.MapMode.READ_ONLY, 0, 
(int)compareeChannel.size());
+               ByteBuffer comparerBuf = 
comparerChannel.map(FileChannel.MapMode.READ_ONLY, 0, 
(int)comparerChannel.size());
+               
+               compareeChannel.close();
+               comparerChannel.close();
+               
+               byte[] toCompare = compareeBuf.array();
+               byte[] compareAgainst = comparerBuf.array();
+               for (int i=0; i< toCompare.length; i++) {
+                   if(toCompare[i] != compareAgainst[i]) {
+                       return false;
+                    }
+                }
+               return true;
+            }
 
     /**
      * This was originally an emulation of [EMAIL PROTECTED] 
File#getParentFile} for JDK 1.1,
@@ -1356,6 +1402,35 @@
         return isUpToDate(sourceTime, destTime, getFileTimestampGranularity());
     }
 
+    
+    /**
+     * A close that throws no exception when something goes wrong.
+     * Do nothing if object is null ref.
+     * Avoids duplicate close methods.
+     * @param o the object representing reader/writer input/output
+     */
+    
+    public static void close(Object o) {
+       if (o != null) {
+               try {
+                       if (o instanceof Writer) {
+                               Writer w = (Writer)o;
+                               w.close();
+                       } else if (o instanceof Reader) {
+                               Reader r = (Reader)o;
+                               r.close();
+                       } else if (o instanceof OutputStream) {
+                               OutputStream os = (OutputStream)o;
+                               os.close();
+                       } else if (o instanceof InputStream) {
+                               InputStream is = (InputStream)o;
+                               is.close();
+                       }
+               } catch (IOException e) {
+                       //do nothing
+               }
+       }
+    }
 
     /**
      * close a writer without throwing any exception if something went wrong.
Index: JavaVersionTest.java
===================================================================
RCS file: JavaVersionTest.java
diff -N JavaVersionTest.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ JavaVersionTest.java        1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,60 @@
+/*
+ * Created on 16-Dec-2004
+ *
+ */
+package org.apache.tools.ant.util;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * @author it-kevin
+ */
+public class JavaVersionTest extends TestCase {
+
+       /*
+        * @see TestCase#setUp()
+        */
+       protected void setUp() throws Exception {
+               super.setUp();
+       }
+
+       /*
+        * @see TestCase#tearDown()
+        */
+       protected void tearDown() throws Exception {
+               super.tearDown();
+       }
+
+       /**
+        * Constructor for JavaVersionTest.
+        * @param name
+        */
+       public JavaVersionTest(String name) {
+               super(name);
+       }
+
+       public static Test suite() {
+               TestSuite suite = new TestSuite();
+               suite.addTest(new JavaVersionTest("testVersionJDK14"));
+               return suite;
+       }
+       
+       public void testVersionJDK14() {
+               try {
+                       boolean version = false;
+                       if 
((!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_2))
+                               && 
(!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_3))
+                                       && 
(!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_1))
+                                       && 
(!JavaEnvUtils.getJavaVersion().equals(JavaEnvUtils.JAVA_1_0))) {
+                               version = true;
+                       }
+                       assertTrue(version);
+                       System.out.println(System.getProperty("java.version"));
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       fail();
+               }
+       }
+}

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

Reply via email to