]> uap-core.de Git - rssreader.git/commitdiff
load application properties in java, not in the C toolkit code
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Tue, 16 Dec 2025 17:39:20 +0000 (18:39 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Tue, 16 Dec 2025 17:39:20 +0000 (18:39 +0100)
ui-java/src/main/java/de/unixwork/ui/Toolkit.java

index 1bb9303c6e8466f6a0737c3ed9976ad071768104..0e2a7298bad8b0b0671bfcb3df3ecce703fa7ade 100644 (file)
@@ -1,17 +1,24 @@
 package de.unixwork.ui;
 
+import java.io.*;
 import java.lang.foreign.*;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Properties;
 
 public class Toolkit {
     private static Toolkit instance;
 
     private Application app;
 
+    private Properties appProperties = new Properties();
+    byte[] propertiesData;
+
     private HashMap<Long, UiObject> toplevelObjects = new HashMap<>();
     private HashMap<Long, Document> documents = new HashMap<>();
     private HashMap<Long, Context> contexts = new HashMap<>(); // TODO: maybe we can replace the UiObject and Document maps with just this context map
@@ -57,11 +64,32 @@ public class Toolkit {
     private ArrayList<Menu> sourceListMenuBuilderCache = new ArrayList<>();
 
     private Toolkit(String appName) {
+        try {
+            loadAppProperties(appName);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
         // load shared library
         System.loadLibrary("uitk");
         linker = Linker.nativeLinker();
         lib = SymbolLookup.loaderLookup();
 
+        // set properties data if available
+        if(propertiesData != null) {
+            MemorySegment ui_set_properties_data_addr = lib.find("ui_set_properties_data").orElseThrow();
+            MethodHandle ui_set_properties_data = linker.downcallHandle(ui_set_properties_data_addr, FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_LONG));
+
+            try (Arena arena = Arena.ofShared()){
+                MemorySegment segment = arena.allocate(propertiesData.length);
+                segment.asByteBuffer().put(propertiesData);
+                ui_set_properties_data.invoke(segment, (long)propertiesData.length);
+            } catch (Throwable e) {
+                throw new RuntimeException(e);
+            }
+            propertiesData = null;
+        }
+
         // get init function
         MemorySegment ui_init_addr = lib.find("ui_init").orElseThrow();
         FunctionDescriptor ui_init_sig = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
@@ -89,6 +117,34 @@ public class Toolkit {
         }
     }
 
+    public void loadAppProperties(String appName) throws IOException {
+        String path = Toolkit.getAppConfigPath(appName);
+        if(path == null) {
+            return;
+        }
+        if(path != null) {
+            File f = new File(path);
+            if(!f.exists()) {
+                return;
+            }
+            try {
+                propertiesData = Files.readAllBytes(Path.of(path));
+            } catch (IOException e) {
+                throw e;
+            }
+
+            try (ByteArrayInputStream in = new ByteArrayInputStream(propertiesData)) {
+                appProperties.load(in);
+            } catch (IOException e) {
+                throw e;
+            }
+        }
+    }
+
+    public Properties getAppProperties() {
+        return appProperties;
+    }
+
     public void setIsObjRegEnabled(boolean value) {
         isObjRegEnabled = value;
     }
@@ -719,6 +775,41 @@ public class Toolkit {
         }
     }
 
+    public static String getAppDir(String appName) {
+        if(appName == null || appName.isEmpty()) {
+            return null;
+        }
+
+        String home = System.getProperty("user.home");
+        String os = System.getProperty("os.name");
+        if(os.startsWith("Windows")) {
+            // windows
+            return home + "\\AppData\\Roaming\\" + appName;
+        } else if(os.startsWith("Mac OS X")) {
+            // macOS
+            return home + "/Library/Application Support/" + appName;
+        }
+
+        // unix
+        String xdgConfigHome = System.getenv("XDG_CONFIG_HOME");
+        if(xdgConfigHome != null) {
+            if(xdgConfigHome.endsWith("/")) {
+                xdgConfigHome = xdgConfigHome.substring(0, xdgConfigHome.length()-1);
+            }
+            return xdgConfigHome + "/" + appName;
+        } else {
+            return home + "/.config/" + appName;
+        }
+    }
+
+    public static String getAppConfigPath(String appName) {
+        String configPath = getAppDir(appName);
+        if(configPath == null) {
+            return null;
+        }
+        return configPath + File.separator + "application.properties";
+    }
+
     public static String getConfigPath() {
         ToolkitFuncs ui = ToolkitFuncs.getInstance();
         try {