Merge pull request #180 from mikeprimm/master

Make JSON file updates more transactional, to prevent reading of partially written files
This commit is contained in:
mikeprimm 2011-05-31 12:05:24 -07:00
commit 852c185b0b

View File

@ -75,14 +75,18 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
protected void writeConfiguration() { protected void writeConfiguration() {
File outputFile; File outputFile;
File outputTempFile;
JSONObject clientConfiguration = new JSONObject(); JSONObject clientConfiguration = new JSONObject();
plugin.events.trigger("buildclientconfiguration", clientConfiguration); plugin.events.trigger("buildclientconfiguration", clientConfiguration);
outputFile = getStandaloneFile("dynmap_config.json"); outputFile = getStandaloneFile("dynmap_config.json");
outputTempFile = getStandaloneFile("dynmap_config.json.new");
try { try {
FileOutputStream fos = new FileOutputStream(outputFile); FileOutputStream fos = new FileOutputStream(outputTempFile);
fos.write(clientConfiguration.toJSONString().getBytes()); fos.write(clientConfiguration.toJSONString().getBytes());
fos.close(); fos.close();
outputFile.delete();
outputTempFile.renameTo(outputFile);
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
Log.severe("Exception while writing JSON-configuration-file.", ex); Log.severe("Exception while writing JSON-configuration-file.", ex);
} catch (IOException ioe) { } catch (IOException ioe) {
@ -92,6 +96,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
protected void writeUpdates() { protected void writeUpdates() {
File outputFile; File outputFile;
File outputTempFile;
//Handles Updates //Handles Updates
for (DynmapWorld dynmapWorld : plugin.mapManager.getWorlds()) { for (DynmapWorld dynmapWorld : plugin.mapManager.getWorlds()) {
World world = dynmapWorld.world; World world = dynmapWorld.world;
@ -102,10 +107,13 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
plugin.events.trigger("buildclientupdate", clientUpdate); plugin.events.trigger("buildclientupdate", clientUpdate);
outputFile = getStandaloneFile("dynmap_" + world.getName() + ".json"); outputFile = getStandaloneFile("dynmap_" + world.getName() + ".json");
outputTempFile = getStandaloneFile("dynmap_" + world.getName() + ".json.new");
try { try {
FileOutputStream fos = new FileOutputStream(outputFile); FileOutputStream fos = new FileOutputStream(outputTempFile);
fos.write(Json.stringifyJson(update).getBytes()); fos.write(Json.stringifyJson(update).getBytes());
fos.close(); fos.close();
outputFile.delete();
outputTempFile.renameTo(outputFile);
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
Log.severe("Exception while writing JSON-file.", ex); Log.severe("Exception while writing JSON-file.", ex);
} catch (IOException ioe) { } catch (IOException ioe) {
@ -119,13 +127,15 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
protected void handleWebChat() { protected void handleWebChat() {
File webchatFile = getStandaloneFile("dynmap_webchat.json"); File webchatFile = getStandaloneFile("dynmap_webchat.json");
File webchatTempFile = getStandaloneFile("dynmap_webchat.json.new");
if (webchatFile.exists() && lastTimestamp != 0) { if (webchatFile.exists() && lastTimestamp != 0) {
JSONArray jsonMsgs = null; JSONArray jsonMsgs = null;
try { try {
FileReader inputFileReader = new FileReader(webchatFile); FileReader inputFileReader = new FileReader(webchatTempFile);
jsonMsgs = (JSONArray) parser.parse(inputFileReader); jsonMsgs = (JSONArray) parser.parse(inputFileReader);
inputFileReader.close(); inputFileReader.close();
webchatFile.delete();
webchatTempFile.renameTo(webchatFile);
} catch (IOException ex) { } catch (IOException ex) {
Log.severe("Exception while reading JSON-file.", ex); Log.severe("Exception while reading JSON-file.", ex);
} catch (ParseException ex) { } catch (ParseException ex) {