Added a little fault-tolerance into save() method, saving to temp
file, then renaming if no errors thrown.

See attached for patch.
Index: DOM4JConfiguration.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-commons-sandbox/configuration/src/java/org/apache/commons/configuration/DOM4JConfiguration.java,v

retrieving revision 1.1
diff -u -r1.1 DOM4JConfiguration.java
--- DOM4JConfiguration.java 14 Jan 2003 03:53:12 -0000  1.1
+++ DOM4JConfiguration.java 20 Jan 2003 02:38:48 -0000
@@ -56,7 +56,9 @@
 
 import java.io.BufferedOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.InputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.URL;
@@ -305,7 +307,7 @@
     }
 
     /**
-     * @throws 
+     * @throws
      */
     private void possiblySave()
     {
@@ -336,10 +338,15 @@
     {
         XMLWriter writer = null;
         OutputStream out = null;
+        // write to a temp file in case of errors
+        File temp = null;
         try
         {
+            temp = new File(file.getParentFile(), file.getName() + ".tmp");
+            // in case an exception is thrown, let JVM clean up
+            temp.deleteOnExit();
             OutputFormat outputter = OutputFormat.createPrettyPrint();
-            out = new BufferedOutputStream(new FileOutputStream(file));
+            out = new BufferedOutputStream(new FileOutputStream(temp));
             writer = new XMLWriter(out, outputter);
             writer.write(document);
         }
@@ -353,6 +360,40 @@
             if (writer != null)
             {
                 writer.close();
+            }
+        }
+
+        // no exceptions are thrown, so its safe to overwrite
+        file.delete();
+        if (temp.renameTo(file) == false)
+        {
+            InputStream in = null;
+            /**
+             * fails if the temporary storage directory was on
+             * different volume than the target directory;
+             * attempt a raw copy.
+             */
+            try
+            {
+                out = new FileOutputStream(file);
+                in = new FileInputStream(temp);
+                byte[] data = new byte[10000];
+                int len;
+                while ((len = in.read(data)) != -1)
+                {
+                    out.write(data, 0, len);
+                }
+            }
+            finally
+            {
+                if (out != null)
+                {
+                    out.close();
+                }
+                if (in != null)
+                {
+                    in.close();
+                }
             }
         }
     }
--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to