Leonel FOFOU
2026-07-28 32450e295200b2bc7896518ff74161ff26772e2d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.megatim.manuel.studio;
 
import com.megatim.manuel.core.theme.ManuelTheme;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
 
/**
 * Charge un {@link ManuelTheme} depuis un fichier {@code .properties}.
 *
 * <p>Clés supportées (toutes optionnelles, défauts = charte Sirius) :</p>
 * <pre>
 * accentColor=#ffe3d0
 * buttonColor=#f6f6f6
 * buttonBorderColor=#c9b8a8
 * panelBorderColor=#d1d1d1
 * selectionColor=#ffd9c2
 * hoverColor=#fff3ea
 * textColor=#3a2c20
 * backgroundColor=#ffffff
 * appTitle=Mon Application
 * logo=chemin/vers/logo.png            (relatif au fichier .properties, ou URL)
 * viewerStylesheet=file:/.../mon.css   (remplace la CSS embarquée)
 * extraViewerStylesheets=uri1;uri2     (surcharges, séparées par ;)
 * htmlVars.html.h1=#7a2e00             (toute variable du template HTML)
 * </pre>
 */
public final class ThemeLoader {
 
    private ThemeLoader() {
    }
 
    public static ManuelTheme load(Path propertiesFile) throws IOException {
        Properties p = new Properties();
        try (InputStream in = Files.newInputStream(propertiesFile)) {
            p.load(new InputStreamReader(in, StandardCharsets.UTF_8));
        }
        ManuelTheme.Builder b = ManuelTheme.builder();
        set(p, "accentColor", b::accentColor);
        set(p, "buttonColor", b::buttonColor);
        set(p, "buttonBorderColor", b::buttonBorderColor);
        set(p, "panelBorderColor", b::panelBorderColor);
        set(p, "selectionColor", b::selectionColor);
        set(p, "hoverColor", b::hoverColor);
        set(p, "textColor", b::textColor);
        set(p, "backgroundColor", b::backgroundColor);
        set(p, "appTitle", b::appTitle);
 
        String logo = trimmed(p, "logo");
        if (logo != null) {
            b.logo(toUrl(logo, propertiesFile));
        }
        set(p, "viewerStylesheet", b::viewerStylesheet);
        String extras = trimmed(p, "extraViewerStylesheets");
        if (extras != null) {
            for (String uri : extras.split(";")) {
                if (!uri.isBlank()) b.extraViewerStylesheet(uri.trim());
            }
        }
        for (String key : p.stringPropertyNames()) {
            if (key.startsWith("htmlVars.")) {
                b.htmlVar(key.substring("htmlVars.".length()), p.getProperty(key).trim());
            }
        }
        return b.build();
    }
 
    private static void set(Properties p, String key, java.util.function.Consumer<String> setter) {
        String v = trimmed(p, key);
        if (v != null) setter.accept(v);
    }
 
    private static String trimmed(Properties p, String key) {
        String v = p.getProperty(key);
        return (v != null && !v.trim().isEmpty()) ? v.trim() : null;
    }
 
    private static URL toUrl(String value, Path base) throws IOException {
        if (value.contains("://") || value.startsWith("file:")) {
            return new URL(value);
        }
        Path path = Path.of(value);
        if (!path.isAbsolute()) {
            path = base.getParent().resolve(path);
        }
        return path.toUri().toURL();
    }
}