From 3440a48dba92a4d8281336a21c15fb40784edaf7 Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Mon, 24 Mar 2025 11:11:39 +0100 Subject: [PATCH] fix resource loading --- .../main/java/org/diylc/lang/LangUtil.java | 35 ++++---- .../java/org/diylc/utils/ResourceUtils.java | 83 ++++++++++++++----- .../swing/plugins/config/ConfigPlugin.java | 30 +++---- 3 files changed, 96 insertions(+), 52 deletions(-) diff --git a/diylc/diylc-core/src/main/java/org/diylc/lang/LangUtil.java b/diylc/diylc-core/src/main/java/org/diylc/lang/LangUtil.java index 55b3824e..6312f093 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/lang/LangUtil.java +++ b/diylc/diylc-core/src/main/java/org/diylc/lang/LangUtil.java @@ -125,25 +125,28 @@ public class LangUtil { public static List getAvailableLanguages() { List res = new ArrayList(); - List files = ResourceUtils.getResourceFiles(LANG_DIR); + Map langContents = ResourceUtils.getResourceContents(LANG_DIR); try { - for (File file : files) { - String key = file.getName().replaceFirst("[.][^.]+$", ""); - Map details = new HashMap(); - try (Stream stream = Files.lines( - Paths.get(file.getAbsolutePath()), StandardCharsets.UTF_8)) { - stream.forEach(s -> { - if (s.contains("=")) { - String[] parts = s.split("="); - if (parts.length == 2) - details.put(parts[0].toLowerCase().trim(), parts[1].trim()); + langContents.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> { + String key = entry.getKey().replaceFirst("[.][^.]+$", ""); + Map details = new HashMap(); + try { + String content = entry.getValue(); + String[] lines = content.split("\n"); + for (String line : lines) { + if (line.contains("=")) { + String[] parts = line.split("="); + if (parts.length == 2) + details.put(parts[0].toLowerCase().trim(), parts[1].trim()); + } + } + } catch (Exception e) { + LOG.error("Error loading language file", e); } + res.add(new Language(key, details)); }); - } catch (IOException e) { - LOG.error("Error loading language file", e); - } - res.add(new Language(key, details)); - } Collections.sort(res); return res; } catch (Exception e) { diff --git a/diylc/diylc-core/src/main/java/org/diylc/utils/ResourceUtils.java b/diylc/diylc-core/src/main/java/org/diylc/utils/ResourceUtils.java index 9a638584..88978f89 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/utils/ResourceUtils.java +++ b/diylc/diylc-core/src/main/java/org/diylc/utils/ResourceUtils.java @@ -3,36 +3,75 @@ package org.diylc.utils; import org.apache.log4j.Logger; import org.diylc.lang.LangUtil; -import java.io.File; import java.io.IOException; -import java.net.URISyntaxException; +import java.io.InputStream; import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; public class ResourceUtils { - private static final Logger LOG = Logger.getLogger(LangUtil.class); + private static final Logger LOG = Logger.getLogger(ResourceUtils.class); - public static List getResourceFiles(String dir) { - List files = new ArrayList<>(); - URL url = LangUtil.class.getResource("/" + dir); - Path path = null; + public static Map getResourceContents(String dir) { + Map contents = new HashMap<>(); + try { - path = Paths.get(url.toURI()); - Files.walk(path, 5).forEach(p -> { - if (!p.toFile().isDirectory()) { - files.add(p.toFile()); + // Get all resources in the directory + URL dirUrl = ResourceUtils.class.getClassLoader().getResource(dir); + if (dirUrl != null) { + if (dirUrl.getProtocol().equals("jar")) { + // Running from JAR + String jarPath = dirUrl.getPath().substring(5, dirUrl.getPath().indexOf("!")); + JarFile jarFile = new JarFile(jarPath); + try { + jarFile.stream() + .filter(entry -> entry.getName().startsWith(dir + "/") && !entry.isDirectory()) + .forEach(entry -> { + try { + String relativePath = entry.getName().substring(dir.length() + 1); + // Read the entire file content as string + String content = new String(jarFile.getInputStream(entry).readAllBytes(), StandardCharsets.UTF_8); + contents.put(relativePath, content); + } catch (IOException e) { + LOG.warn("Could not read resource: " + entry.getName(), e); + } + }); + } finally { + try { + jarFile.close(); + } catch (IOException e) { + LOG.warn("Could not close JAR file", e); + } + } + } else { + // Running from filesystem + java.io.File dirFile = new java.io.File(dirUrl.toURI()); + if (dirFile.exists() && dirFile.isDirectory()) { + java.io.File[] files = dirFile.listFiles(); + if (files != null) { + for (java.io.File file : files) { + if (file.isFile()) { + try { + String relativePath = file.getName(); + String content = new String(java.nio.file.Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); + contents.put(relativePath, content); + } catch (IOException e) { + LOG.warn("Could not read file: " + file, e); + } + } + } + } + } } - }); - } catch (URISyntaxException e) { - LOG.error("Error loading language file", e); - } catch (IOException e) { - LOG.error("Error loading language file", e); + } + } catch (Exception e) { + LOG.error("Error loading resources from directory: " + dir, e); } - return files; + + return contents; } } diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/config/ConfigPlugin.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/config/ConfigPlugin.java index 204af055..ba5c9df9 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/config/ConfigPlugin.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/config/ConfigPlugin.java @@ -22,6 +22,7 @@ import java.io.FileInputStream; import java.io.InputStream; import java.util.EnumSet; import java.util.List; +import java.util.Map; import javax.swing.Icon; import org.apache.log4j.Logger; import org.diylc.appframework.miscutils.ConfigurationManager; @@ -174,23 +175,24 @@ public class ConfigPlugin implements IPlugIn { ActionFactory.getInstance() .createConfigAction(plugInPort, "Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU); - List themeFiles = ResourceUtils.getResourceFiles(THEMES_DIR); - if (!themeFiles.isEmpty()) { + Map themeContents = ResourceUtils.getResourceContents(THEMES_DIR); + if (!themeContents.isEmpty()) { XStream xStream = new XStream(new DomDriver()); xStream.addPermission(AnyTypePermission.ANY); swingUI.injectSubmenu(THEME_MENU, IconLoader.Pens.getIcon(), CONFIG_MENU); - for (File file : themeFiles) { - if (file.getName().toLowerCase().endsWith(".xml")) { - try { - InputStream in = new FileInputStream(file); - Theme theme = (Theme) xStream.fromXML(in); - LOG.debug("Found theme: " + theme.getName()); - swingUI.injectMenuAction(ActionFactory.getInstance().createThemeAction(plugInPort, theme), THEME_MENU); - } catch (Exception e) { - LOG.error("Could not load theme file " + file.getName(), e); - } - } - } + themeContents.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> { + if (entry.getKey().toLowerCase().endsWith(".xml")) { + try { + Theme theme = (Theme) xStream.fromXML(entry.getValue()); + LOG.debug("Found theme: " + theme.getName()); + swingUI.injectMenuAction(ActionFactory.getInstance().createThemeAction(plugInPort, theme), THEME_MENU); + } catch (Exception e) { + LOG.error("Could not load theme file " + entry.getKey(), e); + } + } + }); } swingUI.injectSubmenu(COMPONENT_BROWSER_MENU, IconLoader.Hammer.getIcon(), CONFIG_MENU);