From c43b8464a27ffb0254bdef63cfcd9d1243b8539e Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Tue, 24 Jun 2025 23:27:38 +0200 Subject: [PATCH] save .workspace as json (under .workspace.json) falls back on old .workspace implementation --- .../atcontentstudio/io/JsonSerializable.java | 8 ++ .../atcontentstudio/model/Preferences.java | 38 +++++++- .../rpg/atcontentstudio/model/Workspace.java | 95 +++++++++++++++---- .../rpg/atcontentstudio/utils/FileUtils.java | 31 ++++++ 4 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 src/com/gpl/rpg/atcontentstudio/io/JsonSerializable.java diff --git a/src/com/gpl/rpg/atcontentstudio/io/JsonSerializable.java b/src/com/gpl/rpg/atcontentstudio/io/JsonSerializable.java new file mode 100644 index 0000000..cd251a0 --- /dev/null +++ b/src/com/gpl/rpg/atcontentstudio/io/JsonSerializable.java @@ -0,0 +1,8 @@ +package com.gpl.rpg.atcontentstudio.io; + +import java.util.Map; + +public interface JsonSerializable { + Map toMap(); + void fromMap(Map map); +} diff --git a/src/com/gpl/rpg/atcontentstudio/model/Preferences.java b/src/com/gpl/rpg/atcontentstudio/model/Preferences.java index e43c2c0..e8ca1e6 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/Preferences.java +++ b/src/com/gpl/rpg/atcontentstudio/model/Preferences.java @@ -1,19 +1,53 @@ package com.gpl.rpg.atcontentstudio.model; +import com.gpl.rpg.atcontentstudio.io.JsonSerializable; + import java.awt.*; import java.io.Serializable; import java.util.HashMap; import java.util.Map; -public class Preferences implements Serializable { +public class Preferences implements Serializable, JsonSerializable { private static final long serialVersionUID = 2455802658424031276L; public Dimension windowSize = null; - public Map splittersPositions = new HashMap(); + public Map splittersPositions = new HashMap<>(); public Preferences() { } + @Override + public Map toMap() { + Map map = new HashMap(); + + if(windowSize!= null){ + Map windowSizeMap = new HashMap<>(); + windowSizeMap.put("width", windowSize.width); + windowSizeMap.put("height", windowSize.height); + map.put("windowSize", windowSizeMap); + } + + map.put("splittersPositions", splittersPositions); + return map; + } + + @Override + public void fromMap(Map map) { + if(map == null) return; + + Map windowSize1 = (Map) map.get("windowSize"); + if(windowSize1 != null){ + windowSize = new Dimension(((Number) windowSize1.get("width")).intValue(), ((Number) windowSize1.get("height")).intValue()); + } + + Map splitters = (Map) map.get("splittersPositions"); + Map splittersInt = new HashMap<>(splitters.size()); + for (Map.Entry entry : splitters. entrySet()){ + splittersInt.put(entry.getKey(), entry.getValue().intValue()); + } + splittersPositions = splittersInt; + + } } diff --git a/src/com/gpl/rpg/atcontentstudio/model/Workspace.java b/src/com/gpl/rpg/atcontentstudio/model/Workspace.java index 1dcae03..10556e6 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/Workspace.java +++ b/src/com/gpl/rpg/atcontentstudio/model/Workspace.java @@ -2,27 +2,29 @@ package com.gpl.rpg.atcontentstudio.model; import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.Notification; +import com.gpl.rpg.atcontentstudio.io.JsonSerializable; import com.gpl.rpg.atcontentstudio.io.SettingsSave; import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.ui.ProjectsTree.ProjectsTreeModel; import com.gpl.rpg.atcontentstudio.ui.WorkerDialog; +import com.gpl.rpg.atcontentstudio.utils.FileUtils; +import org.jsoup.SerializationException; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.io.Serializable; +import java.io.*; import java.nio.file.Files; import java.util.List; import java.util.*; -public class Workspace implements ProjectTreeNode, Serializable { +public class Workspace implements ProjectTreeNode, Serializable, JsonSerializable { private static final long serialVersionUID = 7938633033601384956L; public static final String WS_SETTINGS_FILE = ".workspace"; + public static final String WS_SETTINGS_FILE_JSON = ".workspace.json"; public static Workspace activeWorkspace; @@ -38,6 +40,7 @@ public class Workspace implements ProjectTreeNode, Serializable { public transient ProjectsTreeModel projectsTreeModel = null; public Workspace(File workspaceRoot) { + boolean freshWorkspace = false; baseFolder = workspaceRoot; if (!workspaceRoot.exists()) { try { @@ -49,44 +52,105 @@ public class Workspace implements ProjectTreeNode, Serializable { } } settings = new WorkspaceSettings(this); - settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE); + settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE_JSON); if (!settingsFile.exists()) { try { settingsFile.createNewFile(); + freshWorkspace = true; } catch (IOException e) { Notification.addError("Error creating workspace datafile: " + e.getMessage()); e.printStackTrace(); } + Notification.addSuccess("New workspace created: " + + workspaceRoot.getAbsolutePath()); } - Notification.addSuccess("New workspace created: " - + workspaceRoot.getAbsolutePath()); - save(); + if (freshWorkspace) + save(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put("serialVersionUID", serialVersionUID); + map.put("preferences", preferences.toMap()); + map.put("projectsName", (new ArrayList(projectsName))); + map.put("projectsOpenByName", projectsOpenByName); + List l = new ArrayList<>(knownMapSourcesFolders.size()); + for (File f: knownMapSourcesFolders){ + l.add(f.getPath()); + } + map.put("knownMapSourcesFolders", l); + return map; + } + + @Override + public void fromMap(Map map) { + if(serialVersionUID != (long) map.get("serialVersionUID")){ + throw new SerializationException("wrong seriaVersionUID"); + } + + preferences.fromMap((Map) map.get("preferences")); + + projectsName = new HashSet<>((List) map.getOrDefault("projectsName", new HashSet())); + + projectsOpenByName = (Map) map.getOrDefault("projectsOpenByName", new HashMap() ); + + List knownMapSourcesFolders1 = (List) map.getOrDefault("knownMapSourcesFolders", new ArrayList()); + knownMapSourcesFolders = new HashSet<>(); + if (knownMapSourcesFolders1 != null){ + int size = knownMapSourcesFolders1.size(); + for (String path: knownMapSourcesFolders1) { + //TODO: catch invalid paths...? + knownMapSourcesFolders.add(new File(path)); + } + } + } public static void setActive(File workspaceRoot) { Workspace w; - File f = new File(workspaceRoot, WS_SETTINGS_FILE); - if (!workspaceRoot.exists() || !f.exists()) { - w = new Workspace(workspaceRoot); + File f2 = new File(workspaceRoot, WS_SETTINGS_FILE_JSON); + if (workspaceRoot.exists() && f2.exists()) { + w = loadWorkspaceFromJson(workspaceRoot, f2); + w.refreshTransients(); } else { - w = (Workspace) SettingsSave.loadInstance(f, "Workspace"); - if (w == null) { + Notification.addInfo("Could not find json workspace file. Falling back to binary"); + File f = new File(workspaceRoot, WS_SETTINGS_FILE); + if (!workspaceRoot.exists() || !f.exists()) { w = new Workspace(workspaceRoot); } else { - w.refreshTransients(); + w = (Workspace) SettingsSave.loadInstance(f, "Workspace"); + if (w == null) { + w = new Workspace(workspaceRoot); + w.save(); + } else { + w.refreshTransients(); + } } } activeWorkspace = w; } + private static Workspace loadWorkspaceFromJson(File workspaceRoot, File settingsFile) { + Workspace w = w = new Workspace(workspaceRoot); + String json = FileUtils.readFileToString(settingsFile); + if (json!= null) { + Map map = (Map)FileUtils.fromJsonString(json); + if(map!= null){ + w.fromMap(map); + } + } + return w; + } + public static void saveActive() { activeWorkspace.save(); } public void save() { settings.save(); - SettingsSave.saveInstance(this, settingsFile, "Workspace"); + FileUtils.writeStringToFile(FileUtils.toJsonString(this), settingsFile, "Workspace"); } @Override @@ -356,5 +420,4 @@ public class Workspace implements ProjectTreeNode, Serializable { } return false; } - } diff --git a/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java b/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java index 4797b77..ef74f57 100644 --- a/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java +++ b/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java @@ -5,6 +5,8 @@ import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.io.JsonSerializable; import org.json.simple.JSONArray; import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; import java.io.*; import java.nio.file.Files; @@ -40,6 +42,17 @@ public class FileUtils { return writer.toString(); } + public static Object fromJsonString(String json) { + Object o; + try { + JSONParser parser = new JSONParser(); + o = parser.parse(json); + } catch (ParseException e) { + throw new RuntimeException(e); + } + return o; + } + public static boolean writeStringToFile(String toWrite, File file, String type) { return writeStringToFile(toWrite, file, type, true); } @@ -61,6 +74,24 @@ public class FileUtils { } } + public static String readFileToString(File settingsFile) { + String json; + try{ + FileReader file = new FileReader(settingsFile); + BufferedReader reader = new BufferedReader(file); + StringBuilder builder = new StringBuilder(); + int c; + while ((c = reader.read()) != -1) { + builder.append((char) c); + } + json = builder.toString(); + }catch (IOException e){ + json = null; + e.printStackTrace(); + } + return json; + } + public static void deleteDir(File dir) { if (dir.exists()) { for (File f : dir.listFiles()) {