+
+ deleteFiles.clear();
+
+ // find existing backup files
+ BackupFilenameFilter bff = new BackupFilenameFilter(basename, suffix,
+ digits);
+ File[] backupFiles = dirFile.listFiles(bff);
+ int nextIndexNum = 0;
+
+ if (backupFiles.length == 0)
+ {
+ // No other backup files. Just need to move existing file to backupfile_1
+ nextIndexNum = 1;
+ }
+ else
+ {
+ TreeMap<Integer, File> bfTreeMap = sortBackupFilesAsTreeMap(
+ backupFiles, basename);
+ // bfTreeMap now a sorted list of <Integer index>,<File backupfile>
+ // mappings
+
+ if (reverseOrder)
+ {
+ // backup style numbering
+
+
+ int tempMax = noMax ? -1 : max;
+ // noMax == true means no limits
+ // look for first "gap" in backupFiles
+ // if tempMax is -1 at this stage just keep going until there's a gap,
+ // then hopefully tempMax gets set to the right index (a positive
+ // integer so the loop breaks)...
+ // why do I feel a little uneasy about this loop?..
+ for (int i = 1; tempMax < 0 || i <= max; i++)
+ {
+ if (!bfTreeMap.containsKey(i)) // first index without existent
+ // backupfile
+ {
+ tempMax = i;
+ }
+ }
+
+ File previousFile = null;
+ File fileToBeDeleted = null;
+ for (int n = tempMax; n > 0; n--)
+ {
+ String backupfilename = dir + File.separatorChar
+ + BackupFilenameParts.getBackupFilename(n, basename,
+ suffix, digits);
+ File backupfile_n = new File(backupfilename);
+
+ if (!backupfile_n.exists())
+ {
+ // no "oldest" file to delete
+ previousFile = backupfile_n;
+ fileToBeDeleted = null;
+ continue;
+ }
+
+ // check the modification time of this (backupfile_n) and the previous
+ // file (fileToBeDeleted) if the previous file is going to be deleted
+ if (fileToBeDeleted != null)
+ {
+ File replacementFile = backupfile_n;
+ long fileToBeDeletedLMT = fileToBeDeleted.lastModified();
+ long replacementFileLMT = replacementFile.lastModified();
+
+ try
+ {
+ File oldestTempFile = nextTempFile(fileToBeDeleted.getName(),
+ dirFile);
+
+ if (fileToBeDeletedLMT > replacementFileLMT)
+ {
+ String fileToBeDeletedLMTString = sdf
+ .format(fileToBeDeletedLMT);
+ String replacementFileLMTString = sdf
+ .format(replacementFileLMT);
+ System.out.println("WARNING! I am set to delete backupfile "
+ + fileToBeDeleted.getName()
+ + " has modification time "
+ + fileToBeDeletedLMTString
+ + " which is newer than its replacement "
+ + replacementFile.getName()
+ + " with modification time "
+ + replacementFileLMTString);
+
+ boolean delete = confirmNewerDeleteFile(fileToBeDeleted,
+ replacementFile, true);
+
+ if (delete)
+ {
+ // User has confirmed delete -- no need to add it to the list
+ fileToBeDeleted.delete();
+ }
+ else
+ {
+ fileToBeDeleted.renameTo(oldestTempFile);
+ }
+ }
+ else
+ {
+ fileToBeDeleted.renameTo(oldestTempFile);
+ addDeleteFile(oldestTempFile);
+ }
+
+ } catch (Exception e)
+ {
+ System.out.println(
+ "Error occurred, probably making new temp file for '"
+ + fileToBeDeleted.getName() + "'");
+ e.printStackTrace();
+ }
+
+ // reset
+ fileToBeDeleted = null;
+ }
+
+ if (!noMax && n == tempMax && backupfile_n.exists())
+ {
+ fileToBeDeleted = backupfile_n;
+ }
+ else
+ {
+ if (previousFile != null)
+ {
+ ret = ret && backupfile_n.renameTo(previousFile);
+ }
+ }
+
+ previousFile = backupfile_n;
+ }
+
+ // index to use for the latest backup
+ nextIndexNum = 1;
+ }
+ else
+ {
+ // version style numbering (with earliest file deletion if max files
+ // reached)
+
+ bfTreeMap.values().toArray(backupFiles);
+
+ // noMax == true means keep all backup files
+ if ((!noMax) && bfTreeMap.size() >= max)
+ {
+ // need to delete some files to keep number of backups to designated
+ // max
+ int numToDelete = bfTreeMap.size() - max + 1;
+ // the "replacement" file is the latest backup file being kept (it's
+ // not replacing though)
+ File replacementFile = numToDelete < backupFiles.length
+ ? backupFiles[numToDelete]
+ : null;
+ for (int i = 0; i < numToDelete; i++)
+ {
+ // check the deletion files for modification time of the last
+ // backupfile being saved
+ File fileToBeDeleted = backupFiles[i];
+ boolean delete = true;
+
+ boolean newer = false;
+ if (replacementFile != null)
+ {
+ long fileToBeDeletedLMT = fileToBeDeleted.lastModified();
+ long replacementFileLMT = replacementFile != null
+ ? replacementFile.lastModified()
+ : Long.MAX_VALUE;
+ if (fileToBeDeletedLMT > replacementFileLMT)
+ {
+ String fileToBeDeletedLMTString = sdf
+ .format(fileToBeDeletedLMT);
+ String replacementFileLMTString = sdf
+ .format(replacementFileLMT);
+
+ System.out
+ .println("WARNING! I am set to delete backupfile '"
+ + fileToBeDeleted.getName()
+ + "' has modification time "
+ + fileToBeDeletedLMTString
+ + " which is newer than the oldest backupfile being kept '"
+ + replacementFile.getName()
+ + "' with modification time "
+ + replacementFileLMTString);
+
+ delete = confirmNewerDeleteFile(fileToBeDeleted,
+ replacementFile, false);
+ if (delete)
+ {
+ // User has confirmed delete -- no need to add it to the list
+ fileToBeDeleted.delete();
+ delete = false;
+ }
+ else
+ {
+ // keeping file, nothing to do!
+ }
+ }
+ }
+ if (delete)
+ {
+ addDeleteFile(fileToBeDeleted);
+ }
+
+ }
+
+ }
+
+ nextIndexNum = bfTreeMap.lastKey() + 1;
+ }
+ }
+
+ // Let's make the new backup file!! yay, got there at last!
+ String latestBackupFilename = dir + File.separatorChar
+ + BackupFilenameParts.getBackupFilename(nextIndexNum, basename,
+ suffix, digits);
+ ret |= file.renameTo(new File(latestBackupFilename));
+
+ if (tidyUp)
+ {
+ tidyUpFiles();
+ }
+
+ return ret;
+ }
+
+ private static File nextTempFile(String filename, File dirFile)
+ throws IOException
+ {
+ File temp = null;
+ COUNT: for (int i = 1; i < 1000; i++)
+ {
+ File trythis = new File(dirFile,
+ filename + '~' + Integer.toString(i));
+ if (!trythis.exists())
+ {
+ temp = trythis;
+ break COUNT;
+ }
+
+ }
+ if (temp == null)
+ {
+ temp = File.createTempFile(filename, TEMP_FILE_EXT, dirFile);
+ }
+ return temp;
+ }
+
+ private void tidyUpFiles()
+ {
+ deleteOldFiles();
+ }
+
+ private static boolean confirmNewerDeleteFile(File fileToBeDeleted,
+ File replacementFile, boolean replace)
+ {
+ StringBuilder messageSB = new StringBuilder();
+
+ File ftbd = fileToBeDeleted;
+ String ftbdLMT = sdf.format(ftbd.lastModified());
+ String ftbdSize = Long.toString(ftbd.length());
+
+ File rf = replacementFile;
+ String rfLMT = sdf.format(rf.lastModified());
+ String rfSize = Long.toString(rf.length());
+
+ int confirmButton = JvOptionPane.NO_OPTION;
+ if (replace)
+ {
+ File saveFile = null;
+ try