improve json saving to file

This commit is contained in:
OMGeeky
2025-06-24 21:50:52 +02:00
parent 1cbcd5b661
commit a3ffecfd23
7 changed files with 1644 additions and 1657 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,7 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import java.io.*; import java.io.*;
@@ -108,22 +107,8 @@ public class WorkspaceSettings {
} }
json.put(VERSION_KEY, SETTINGS_VERSION); json.put(VERSION_KEY, SETTINGS_VERSION);
StringWriter writer = new JsonPrettyWriter(); String toWrite = FileUtils.toJsonString(json);
try { FileUtils.writeStringToFile(toWrite, file, "Workspace settings");
JSONObject.writeJSONString(json, writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(file);
w.write(toWrite);
w.close();
Notification.addSuccess("Workspace settings saved.");
} catch (IOException e) {
Notification.addError("Error while saving workspace settings : " + e.getMessage());
e.printStackTrace();
}
} }
public void resetDefault() { public void resetDefault() {

View File

@@ -5,6 +5,7 @@ import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.*; import com.gpl.rpg.atcontentstudio.model.*;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
@@ -157,26 +158,13 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return; return;
} }
StringWriter writer = new JsonPrettyWriter();
try { String toWrite = FileUtils.toJsonString(dataToSave);
JSONArray.writeJSONString(dataToSave, writer); if(FileUtils.writeStringToFile(toWrite, jsonFile, "JSON file '"+jsonFile.getAbsolutePath()+"'")){
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(jsonFile);
w.write(toWrite);
w.close();
for (E element : this) { for (E element : this) {
element.state = GameDataElement.State.saved; element.state = GameDataElement.State.saved;
} }
Notification.addSuccess("Json file " + jsonFile.getAbsolutePath() + " saved.");
} catch (IOException e) {
Notification.addError("Error while writing json file " + jsonFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
} }
} }

View File

@@ -4,6 +4,7 @@ import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@@ -73,16 +74,10 @@ public abstract class JSONElement extends GameDataElement {
public abstract Map toJson(); public abstract Map toJson();
public String toJsonString() { public String toJsonString() {
StringWriter writer = new JsonPrettyWriter(); Map json = this.toJson();
try { return FileUtils.toJsonString(json);
JSONObject.writeJSONString(this.toJson(), writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
return writer.toString();
} }
@Override @Override
public GameDataSet getDataSet() { public GameDataSet getDataSet() {
if (parent == null) { if (parent == null) {

View File

@@ -145,16 +145,12 @@ public class ResourcesCompactor {
private Minify jsonMinifier = new Minify(); private Minify jsonMinifier = new Minify();
private void writeJson(List<Map> dataToSave, File target) { private void writeJson(List<Map> dataToSave, File target) {
StringWriter writer = new JsonPrettyWriter(); String toWrite = FileUtils.toJsonString(dataToSave);
try { toWrite = jsonMinifier.minify(toWrite);
JSONArray.writeJSONString(dataToSave, writer); FileUtils.writeStringToFile(toWrite, target, null);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try { try {
FileWriter w = new FileWriter(target); FileWriter w = new FileWriter(target);
w.write(jsonMinifier.minify(toWrite)); w.write(toWrite);
w.close(); w.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -6,6 +6,7 @@ import com.gpl.rpg.atcontentstudio.model.*;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@@ -155,24 +156,12 @@ public class WriterModeDataSet implements ProjectTreeNode, Serializable {
return; return;
} }
StringWriter writer = new JsonPrettyWriter();
try { String toWrite = FileUtils.toJsonString(dataToSave);
JSONArray.writeJSONString(dataToSave, writer); if(FileUtils.writeStringToFile(toWrite, writerFile, "Json file " + writerFile.getAbsolutePath())) {
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(writerFile);
w.write(toWrite);
w.close();
for (WriterModeData element : writerModeDataList) { for (WriterModeData element : writerModeDataList) {
element.state = GameDataElement.State.saved; element.state = GameDataElement.State.saved;
} }
Notification.addSuccess("Json file " + writerFile.getAbsolutePath() + " saved.");
} catch (IOException e) {
Notification.addError("Error while writing json file " + writerFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
} }
} }

View File

@@ -1,219 +1,266 @@
package com.gpl.rpg.atcontentstudio.utils; package com.gpl.rpg.atcontentstudio.utils;
import java.io.*; import com.gpl.rpg.atcontentstudio.Notification;
import java.nio.file.Files; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import java.nio.file.Path; import org.json.simple.JSONArray;
import java.nio.file.Paths; import org.json.simple.JSONObject;
import java.nio.file.StandardCopyOption;
import java.util.zip.ZipEntry; import java.io.*;
import java.util.zip.ZipOutputStream; import java.nio.file.Files;
import java.nio.file.Path;
public class FileUtils { import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public static void deleteDir(File dir) { import java.util.List;
if (dir.exists()) { import java.util.Map;
for (File f : dir.listFiles()) { import java.util.zip.ZipEntry;
if (f.isDirectory()) { import java.util.zip.ZipOutputStream;
deleteDir(f);
} else { public class FileUtils {
f.delete();
} public static String toJsonString(Map json) {
} StringWriter writer = new JsonPrettyWriter();
dir.delete(); try {
} JSONObject.writeJSONString(json, writer);
} } catch (IOException e) {
//Impossible with a StringWriter
public static void copyFile(File sourceLocation, File targetLocation) { }
try { return writer.toString();
InputStream in = new FileInputStream(sourceLocation); }
OutputStream out = new FileOutputStream(targetLocation); public static String toJsonString(List json) {
StringWriter writer = new JsonPrettyWriter();
// Copy the bits from instream to outstream try {
byte[] buf = new byte[1024]; JSONArray.writeJSONString(json, writer);
int len; } catch (IOException e) {
try { //Impossible with a StringWriter
while ((len = in.read(buf)) > 0) { }
out.write(buf, 0, len); return writer.toString();
} }
} catch (IOException e) {
// TODO Auto-generated catch block public static boolean writeStringToFile(String toWrite, File file, String type) {
} finally { return writeStringToFile(toWrite, file, type, true);
try { }
in.close(); public static boolean writeStringToFile(String toWrite, File file, String type, boolean notifyOnSuccess) {
} catch (IOException e) { try {
// TODO Auto-generated catch block FileWriter w = new FileWriter(file);
} w.write(toWrite);
try { w.close();
out.close(); if(type != null) {
} catch (IOException e) { Notification.addSuccess(type + " saved.");
// TODO Auto-generated catch block }
} return true;
} } catch (IOException e) {
} catch (FileNotFoundException e1) { if(type != null) {
// TODO Auto-generated catch block Notification.addError("Error while saving " + type + " : " + e.getMessage());
} }
} e.printStackTrace();
return false;
private static final int BUFFER = 2048; }
}
public static void writeToZip(File folder, File target) {
try { public static void deleteDir(File dir) {
FileOutputStream dest = new FileOutputStream(target); if (dir.exists()) {
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); for (File f : dir.listFiles()) {
zipDir(folder, "", out); if (f.isDirectory()) {
out.flush(); deleteDir(f);
out.close(); } else {
} catch (Exception e) { f.delete();
// TODO Auto-generated catch block }
e.printStackTrace(); }
} dir.delete();
}
} }
/** public static void copyFile(File sourceLocation, File targetLocation) {
* cp sourceFolder/* targetFolder/ try {
* InputStream in = new FileInputStream(sourceLocation);
* @param sourceFolder OutputStream out = new FileOutputStream(targetLocation);
* @param targetFolder
*/ // Copy the bits from instream to outstream
public static void copyOver(File sourceFolder, File targetFolder) { byte[] buf = new byte[1024];
if (!sourceFolder.isDirectory() || !targetFolder.isDirectory()) return; int len;
for (File f : sourceFolder.listFiles()) { try {
if (Files.isSymbolicLink(f.toPath())) { while ((len = in.read(buf)) > 0) {
//Skip symlinks out.write(buf, 0, len);
continue; }
} else if (f.isDirectory()) { } catch (IOException e) {
File dest = new File(targetFolder, f.getName()); // TODO Auto-generated catch block
if (!dest.exists()) { } finally {
dest.mkdir(); try {
} in.close();
copyOver(f, dest); } catch (IOException e) {
} else { // TODO Auto-generated catch block
copyFile(f, new File(targetFolder, f.getName())); }
} try {
} out.close();
} } catch (IOException e) {
// TODO Auto-generated catch block
private static void zipDir(File dir, String prefix, ZipOutputStream zos) { }
if (prefix != "") { }
prefix = prefix + File.separator; } catch (FileNotFoundException e1) {
} // TODO Auto-generated catch block
for (File f : dir.listFiles()) { }
if (f.isDirectory()) { }
zipDir(f, prefix + f.getName(), zos);
} else { private static final int BUFFER = 2048;
FileInputStream fis;
try { public static void writeToZip(File folder, File target) {
fis = new FileInputStream(f); try {
BufferedInputStream origin = new BufferedInputStream(fis, BUFFER); FileOutputStream dest = new FileOutputStream(target);
ZipEntry entry = new ZipEntry(prefix + f.getName()); ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
try { zipDir(folder, "", out);
zos.putNextEntry(entry); out.flush();
int count; out.close();
byte data[] = new byte[BUFFER]; } catch (Exception e) {
while ((count = origin.read(data, 0, BUFFER)) != -1) { // TODO Auto-generated catch block
zos.write(data, 0, count); e.printStackTrace();
zos.flush(); }
}
} catch (IOException e) { }
// TODO Auto-generated catch block
e.printStackTrace(); /**
} finally { * cp sourceFolder/* targetFolder/
try { *
origin.close(); * @param sourceFolder
} catch (IOException e) { * @param targetFolder
// TODO Auto-generated catch block */
e.printStackTrace(); public static void copyOver(File sourceFolder, File targetFolder) {
} if (!sourceFolder.isDirectory() || !targetFolder.isDirectory()) return;
} for (File f : sourceFolder.listFiles()) {
} catch (FileNotFoundException e) { if (Files.isSymbolicLink(f.toPath())) {
// TODO Auto-generated catch block //Skip symlinks
e.printStackTrace(); continue;
} } else if (f.isDirectory()) {
} File dest = new File(targetFolder, f.getName());
} if (!dest.exists()) {
} dest.mkdir();
}
public static boolean makeSymlink(File targetFile, File linkFile) { copyOver(f, dest);
Path target = Paths.get(targetFile.getAbsolutePath()); } else {
Path link = Paths.get(linkFile.getAbsolutePath()); copyFile(f, new File(targetFolder, f.getName()));
if (!Files.exists(link)) { }
try { }
Files.createSymbolicLink(link, target); }
} catch (Exception e) {
System.err.println("Failed to create symbolic link to target \"" + targetFile.getAbsolutePath() + "\" as \"" + linkFile.getAbsolutePath() + "\" the java.nio way:"); private static void zipDir(File dir, String prefix, ZipOutputStream zos) {
e.printStackTrace(); if (prefix != "") {
switch (DesktopIntegration.detectedOS) { prefix = prefix + File.separator;
case Windows: }
System.err.println("Trying the Windows way with mklink"); for (File f : dir.listFiles()) {
try { if (f.isDirectory()) {
Runtime.getRuntime().exec( zipDir(f, prefix + f.getName(), zos);
"cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\""); } else {
} catch (IOException e1) { FileInputStream fis;
e1.printStackTrace(); try {
} fis = new FileInputStream(f);
if (!linkFile.exists()) { BufferedInputStream origin = new BufferedInputStream(fis, BUFFER);
System.err.println("Attempting UAC elevation through VBS script."); ZipEntry entry = new ZipEntry(prefix + f.getName());
runWithUac("cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"", 3, linkFile); try {
} zos.putNextEntry(entry);
break; int count;
case MacOS: byte data[] = new byte[BUFFER];
case NIX: while ((count = origin.read(data, 0, BUFFER)) != -1) {
case Other: zos.write(data, 0, count);
System.err.println("Trying the unix way with ln -s"); zos.flush();
try { }
Runtime.getRuntime().exec("ln -s " + targetFile.getAbsolutePath() + " " + linkFile.getAbsolutePath()); } catch (IOException e) {
} catch (IOException e1) { // TODO Auto-generated catch block
e1.printStackTrace(); e.printStackTrace();
} } finally {
break; try {
default: origin.close();
System.out.println("Unrecognized OS. Please contact ATCS dev."); } catch (IOException e) {
break; // TODO Auto-generated catch block
e.printStackTrace();
} }
} }
} } catch (FileNotFoundException e) {
if (!Files.exists(link)) { // TODO Auto-generated catch block
System.err.println("Failed to create link \"" + linkFile.getAbsolutePath() + "\" targetting \"" + targetFile.getAbsolutePath() + "\""); e.printStackTrace();
System.err.println("You can try running ATCS with administrative privileges once, or create the symbolic link manually."); }
} }
return true; }
} }
public static File backupFile(File f) { public static boolean makeSymlink(File targetFile, File linkFile) {
try { Path target = Paths.get(targetFile.getAbsolutePath());
Path returned = Files.copy(Paths.get(f.getAbsolutePath()), Paths.get(f.getAbsolutePath() + ".bak"), StandardCopyOption.REPLACE_EXISTING); Path link = Paths.get(linkFile.getAbsolutePath());
return returned.toFile(); if (!Files.exists(link)) {
} catch (IOException e) { try {
e.printStackTrace(); Files.createSymbolicLink(link, target);
} } catch (Exception e) {
return null; System.err.println("Failed to create symbolic link to target \"" + targetFile.getAbsolutePath() + "\" as \"" + linkFile.getAbsolutePath() + "\" the java.nio way:");
} e.printStackTrace();
switch (DesktopIntegration.detectedOS) {
static final String uacBatName = "ATCS_elevateWithUac.bat"; case Windows:
System.err.println("Trying the Windows way with mklink");
public static void runWithUac(String command, int tries, File checkExists) { try {
File tmpFolder = new File(System.getProperty("java.io.tmpdir")); Runtime.getRuntime().exec(
File batFile = new File(tmpFolder, uacBatName); "cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"");
batFile.deleteOnExit(); } catch (IOException e1) {
FileWriter writer; e1.printStackTrace();
try { }
writer = new FileWriter(batFile, false); if (!linkFile.exists()) {
writer.write( System.err.println("Attempting UAC elevation through VBS script.");
"@echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n" runWithUac("cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"", 3, linkFile);
+ "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n" }
+ "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n" break;
+ "@cscript %temp%\\sudo.tmp.vbs\r\n" case MacOS:
+ "del /f %temp%\\sudo.tmp.vbs\r\n"); case NIX:
writer.close(); case Other:
while (!checkExists.exists() && tries-- > 0) { System.err.println("Trying the unix way with ln -s");
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", batFile.getAbsolutePath() + " " + command}); try {
} Runtime.getRuntime().exec("ln -s " + targetFile.getAbsolutePath() + " " + linkFile.getAbsolutePath());
} catch (IOException e) { } catch (IOException e1) {
e.printStackTrace(); e1.printStackTrace();
} }
break;
} default:
System.out.println("Unrecognized OS. Please contact ATCS dev.");
} break;
}
}
}
if (!Files.exists(link)) {
System.err.println("Failed to create link \"" + linkFile.getAbsolutePath() + "\" targetting \"" + targetFile.getAbsolutePath() + "\"");
System.err.println("You can try running ATCS with administrative privileges once, or create the symbolic link manually.");
}
return true;
}
public static File backupFile(File f) {
try {
Path returned = Files.copy(Paths.get(f.getAbsolutePath()), Paths.get(f.getAbsolutePath() + ".bak"), StandardCopyOption.REPLACE_EXISTING);
return returned.toFile();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
static final String uacBatName = "ATCS_elevateWithUac.bat";
public static void runWithUac(String command, int tries, File checkExists) {
File tmpFolder = new File(System.getProperty("java.io.tmpdir"));
File batFile = new File(tmpFolder, uacBatName);
batFile.deleteOnExit();
FileWriter writer;
try {
writer = new FileWriter(batFile, false);
writer.write(
"@echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n"
+ "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n"
+ "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n"
+ "@cscript %temp%\\sudo.tmp.vbs\r\n"
+ "del /f %temp%\\sudo.tmp.vbs\r\n");
writer.close();
while (!checkExists.exists() && tries-- > 0) {
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", batFile.getAbsolutePath() + " " + command});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}