001/* ----------------------------------------------------------------------------
002   The Kiwi Toolkit - A Java Class Library
003   Copyright (C) 1998-2004 Mark A. Lindner
004
005   This library is free software; you can redistribute it and/or
006   modify it under the terms of the GNU General Public License as
007   published by the Free Software Foundation; either version 2 of the
008   License, or (at your option) any later version.
009
010   This library is distributed in the hope that it will be useful,
011   but WITHOUT ANY WARRANTY; without even the implied warranty of
012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013   General Public License for more details.
014
015   You should have received a copy of the GNU General Public License
016   along with this library; if not, write to the Free Software
017   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018   02111-1307, USA.
019 
020   The author may be contacted at: mark_a_lindner@yahoo.com
021   ----------------------------------------------------------------------------
022   $Log: BackupFileWriter.java,v $
023   Revision 1.2  2004/05/05 21:36:35  markl
024   comment block updates
025
026   Revision 1.1  2004/03/15 06:08:52  markl
027   New classes.
028   ----------------------------------------------------------------------------
029*/
030
031package kiwi.io;
032
033import java.io.*;
034
035/** A file writer that safely overwrites an existing file. When
036 * the stream is created, a temporary file is opened for writing. The name
037 * of the temporary file is simply <b><i>filename</i>.tmp</b>, where
038 * <i>filename</i> is the file to be written. When the stream is closed,
039 * the following steps are taken:
040 *
041 * <ol>
042 * <li>If the original file exists, it is renamed to
043 * <b><i>filename</i>.bak</b>.
044 * <li>The temporary file is renamed to the original filename.
045 * </ol>
046 *
047 * These steps ensure that the original file is not clobbered during the
048 * update, and that a previous version of the file is always available.
049 *
050 * @author Mark Lindner
051 * @since Kiwi 2.0
052 * @see kiwi.io.BackupFileOutputStream
053 */
054
055public class BackupFileWriter extends FileWriter
056  {
057  private File tempFile, backupFile;
058  private File file;
059  private boolean closed = false;
060
061  /** Create a new <code>BackupFileWriter</code> for the given file.
062   *
063   * @param file The file to write.
064   * @throws java.io.IOException If the temporary file could not be opened for
065   * writing.
066   */
067  
068  public BackupFileWriter(File file) throws IOException
069    {
070    super(getTempFile(file));
071    
072    this.file = file;
073    
074    String path = file.getAbsolutePath();
075    tempFile = new File(path + ".tmp");
076    backupFile = new File(path + ".bak");
077    }
078
079  /** Create a new <code>BackupFileWriter</code> for the given file.
080   *
081   * @param file The path of the file to write.
082   * @throws java.io.IOException If the temporary file could not be opened for
083   * writing.
084   */
085  
086  public BackupFileWriter(String file) throws IOException
087    {
088    this(new File(file));
089    }
090
091  /** Close the writer.
092   *
093   * @throws java.io.IOException If an I/O error occurs.
094   */
095
096  public final void close() throws IOException
097    {
098    if(closed)
099      return;
100    
101    super.close();
102
103    if(backupFile.exists())
104      backupFile.delete();
105
106    if(file.exists())
107      if(! file.renameTo(backupFile))
108        throw(new IOException("Unable to move file to backup file"));
109
110    if(! tempFile.renameTo(file))
111      throw(new IOException("Unable to move temp file to original file"));
112
113    closed = true;
114    }
115
116  /*
117   */
118
119  private static File getTempFile(File file)
120    {
121    String path = file.getAbsolutePath();
122    return(new File(path + ".tmp"));
123    }
124  
125  }
126
127/* end of source file */