/** * @brief Load auctions from a save file, with a pretty splash screen and everything, if * necessary. * <p>I'd like to abstract this, and make it work with arbitrary streams, so that we could * send an XML file of auctions over a network to sync between JBidwatcher instances. */ public void loadAuctions() { XMLElement xmlFile = new XMLElement(true); String loadFile = JConfig.queryConfiguration("savefile", "auctions.xml"); String oldLoad = loadFile; loadFile = JConfig.getCanonicalFile(loadFile, "jbidwatcher", true); if (!loadFile.equals(oldLoad)) { JConfig.setConfiguration("savefile", loadFile); } File toLoad = new File(loadFile); if (toLoad.exists() && toLoad.length() != 0) { try { loadXMLFromFile(loadFile, xmlFile); } catch (IOException ioe) { JConfig.log() .handleException("A serious problem occurred trying to load from auctions.xml.", ioe); MQFactory.getConcrete("Swing") .enqueue( "ERROR Failure to load your saved auctions. Some or all items may be missing."); } catch (XMLParseException xme) { JConfig.log().handleException("Trying to load from auctions.xml.", xme); MQFactory.getConcrete("Swing") .enqueue( "ERROR Failure to load your saved auctions. Some or all items may be missing."); } } else { // This is a common thing, and we don't want to frighten new // users, who are most likely to see it. JConfig.log() .logDebug( "JBW: Failed to load saved auctions, the auctions file is probably not there yet."); JConfig.log().logDebug("JBW: This is not an error, unless you're constantly getting it."); } }
private static void preserveFiles(String filename) { File oldFile = new File(filename); File saveFile = new File(filename + ".temp"); SimpleDateFormat sdf = new SimpleDateFormat("ddMMMyy_HHmm"); String nowStr = sdf.format(new Date()); String retainFilename = makeBackupFilename(filename, nowStr); File retainFile = new File(retainFilename); if (retainFile.exists()) retainFile.delete(); String oldestSave = JConfig.queryConfiguration("save.file.4", ""); if (oldestSave.length() != 0) { File oldest = new File(oldestSave); if (oldest.exists()) { backupByDate(filename, oldest); } } for (int i = 4; i > 0; i--) { JConfig.setConfiguration( "save.file." + i, JConfig.queryConfiguration("save.file." + (i - 1), "")); } File keepFile = new File(retainFilename); if (!oldFile.renameTo(keepFile)) { JConfig.log() .logDebug( "Renaming the old file (" + oldFile + ") to the retain file (" + keepFile + ") failed!"); } JConfig.setConfiguration("save.file.0", retainFilename); File standard = new File(filename); if (!saveFile.renameTo(standard)) { JConfig.log() .logDebug( "Renaming the new file (" + saveFile + ") to the standard filename (" + standard + ") failed!"); } }
/** * @brief Save auctions out to the savefile, in XML format. * <p>Similar to the loadAuctions code, this would be nice if it were abstracted to write to * any outputstream, allowing us to write to a remote node to update it with our auctions and * snipes. * @return - true if it successfully saved, false if an error occurred. */ public boolean saveAuctions() { XMLElement auctionsData = AuctionServerManager.getInstance().toXML(); String oldSave = JConfig.queryConfiguration("savefile", "auctions.xml"); String saveFilename = JConfig.getCanonicalFile( JConfig.queryConfiguration("savefile", "auctions.xml"), "jbidwatcher", false); String newSave = saveFilename; // If there's no data to save, then pretend we did it. if (auctionsData == null) return true; ensureDirectories(saveFilename); boolean swapFiles = needSwapSaves(saveFilename); if (!saveFilename.equals(oldSave)) { JConfig.setConfiguration("savefile", saveFilename); } // If we already have a save file, preserve its name, and write // the new one to '.temp'. if (swapFiles) { newSave = saveFilename + ".temp"; File newSaveFile = new File(newSave); if (newSaveFile.exists()) newSaveFile.delete(); } StringBuffer buf = buildSaveBuffer(auctionsData, null); boolean saveDone = true; // Dump the save file out! try { PrintStream ps = new PrintStream(new FileOutputStream(newSave)); ps.println(buf); ps.close(); } catch (IOException e) { JConfig.log().handleException("Failed to save auctions.", e); saveDone = false; } // If the save was complete, and we have to swap old/new files, // then [remove prior '.old' file if necessary], save current XML // as '.old', and move most recent save file to be just a normal // save file. if (saveDone && swapFiles) { preserveFiles(saveFilename); } return saveDone; }
private static void backupByDate(String filename, File oldest) { SimpleDateFormat justDateFmt = new SimpleDateFormat("ddMMMyy"); String justDate = justDateFmt.format(new Date()); String oldBackup = makeBackupFilename(filename, justDate); File oldDateBackup = new File(oldBackup); if (oldDateBackup.exists()) { oldDateBackup.delete(); File newDateBackup = new File(oldBackup); oldest.renameTo(newDateBackup); } else { oldest.renameTo(oldDateBackup); String oldestByDate = JConfig.queryConfiguration("save.bydate.4", ""); for (int i = 4; i > 0; i--) { JConfig.setConfiguration( "save.bydate." + i, JConfig.queryConfiguration("save.bydate." + (i - 1), "")); } JConfig.setConfiguration("save.bydate.0", oldBackup); File deleteMe = new File(oldestByDate); deleteMe.delete(); } }
private static boolean needSwapSaves(String saveName) { File oldFile = new File(saveName); return oldFile.exists(); }
private static void ensureDirectories(String saveFilename) { // Thanks to Gabor Liptak for this recommendation... File saveParent = new File(saveFilename); saveParent = saveParent.getParentFile(); if (!saveParent.exists()) saveParent.mkdirs(); // This can fail, but we don't mind. }