Config rework (#2823)

# Description of Changes

Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: a <a>
This commit is contained in:
Anthony Stirling 2025-01-31 11:00:03 +00:00 committed by GitHub
parent 3dd8b53f85
commit 382f5603a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 544 additions and 199 deletions

6
.github/release.yml vendored
View File

@ -1,10 +1,4 @@
changelog:
exclude:
labels:
- Documentation
- Test
- Github
categories:
- title: Bug Fixes
labels:

View File

@ -293,9 +293,6 @@ dependencies {
implementation("io.github.pixee:java-security-toolkit:1.2.1")
// implementation "org.yaml:snakeyaml:2.2"
implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4'
// Exclude Tomcat and include Jetty
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
implementation "org.springframework.boot:spring-boot-starter-jetty:$springBootVersion"

Binary file not shown.

View File

@ -865,6 +865,34 @@ FaSYF1lb13TNIRT1q1My
=MTP+
-----END PGP PUBLIC KEY BLOCK-----
pub A6144824624A3CBA
uid Leangen (Artifacts) <info@leangen.io>
sub 95E9D9B03269AB9F
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFf5E+EBCACtP5tSlTkLEBjJuzSC+eVGpSCusCZ4Nqvqui+uJf+yN64ZOJET
DbNgJlJTEmwkUFNdGWOg1hnhpBxjBKzAGcCf8YxmW2MJQt88C+DczgYcs3Jhn0GM
0RcvxfdUHLdyVTxCM4iDGOPu8v+Rr9gsUW//rps+vQRLrBmSqIo4rnSUOhJPy1Gn
ma+hZcG95rDiQ3bCbkEYbtqW/fPes8u8MyaUxxeUpPufLrLVMqNCYrO/FeOubfo+
JypWmuq9XTJQYXEGjXJ7t158LrHGaFtrTnt7CvrpuZGqKyjtjeUXQZ5Qu52hINKD
eCZgyb7jmNd+MpP/a8YfkX/Mmr6GBgXwojXZABEBAAG0JUxlYW5nZW4gKEFydGlm
YWN0cykgPGluZm9AbGVhbmdlbi5pbz65AQ0EV/kT4QEIAMLQGyvUrPO/NGPRmNvE
VfvIk2bpkn7BAPS9aEycLShW8Jvf8I0S8vF/O6tIPeNUz+N6ZANpM+plCUHhJoCg
96fb2jpt/DFa6NNchnXAcIe8q32blBVStVM0z9A4JPcHOWxVrn4SNQMQUdIbt6ml
P0O2P3f5YERpVjY813Awv997dJUJ0UpjpgnpBwOOVvcWaccYmP2eSuFk5NgmjHS+
47V1FjTel/lBBXRfk/36GaU8POqlac/lKFFq2Wri2S72eWFV2pzhDEaeEUo5Pe1Y
anHVbpbXO4JVz4YduwXse183r2B+8b5L6Et9xImzmqMPLKvnnEHB6nBl4K0ggIow
QRcAEQEAAYkBHwQYAQIACQUCV/kT4QIbDAAKCRCmFEgkYko8uvpEB/9thgmJAN9K
LALzQHPCh0rsX6MfOGvnomaSBDkp6BNQGLqIrggeU80Gpg5lFwOEfIFYgP24nHoj
PnfqUZ3YaoJm27p49D5m0RpC6fN9OCM+i6kdEL2AfjeBFG3D/1JW97bs9D4Rcdgq
AIt125Abqxt/hHNFXqHklB+s82MgT4R3RlAhajOQCoKv8edvffftzdGp2x0DW+Ho
kyxnEyRMk/6nad5QiUyWEwbxi7gc1xh7IkuCC+fvWsSPIxM53ov9PSIcavKPZ496
x0aKAXs2IZB0h0UBVChgHpv9smnm/ylvSJf8xMAkazYF35a6wapsDWORTAvxdvyd
d1zmjysrhIJd
=FiL9
-----END PGP PUBLIC KEY BLOCK-----
pub AECDB81D38EA9C89
uid Robin Stocker (GitHub Actions) <robin@nibor.org>
@ -2063,6 +2091,42 @@ Dku+hCB3xh5oGGk7FagBQj0vvu1g7b6H
=q86m
-----END PGP PUBLIC KEY BLOCK-----
pub EBA8E97B15086E24
uid deltazulu <deltazulu@google.com>
sub 0BCD135DED52B043
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGBjjp8BDADIsTk3ZUN13dtbqz6LJvRI4QYOEQlpQmYkXW5cAd9kuQLwU7AM
ikDxvzUGVIRfnB02hVgNiqizaLKWzdg85+eYpsFvXnSc9pUSAFolgEnkTuxiwuvc
JOx6kfYjCOmyAJpdjbArikSurC5knsjrCxHlvU4lRoT4YANXseU5EH+DCvRnHSWR
S4Ibkz9z/PuVC1SnnzrmY2gUvnT1F3Ndr2VsP6PVoJyBaKOGyvJh1wjnBHODKv5o
NFAfowrZ6sDuZOjdmrWoA44+u+62Hk0RqCZL/R77LeL32fkXF3PrXzw64wMzHRzR
ckCoUsxziLYIj7+cJdY2jzzjz7C+S/SYN3VWFZP0fPbGxMGoAfWG0Hg0eaT9PnAU
GDFlWEYJW07JQBnbFHQAiCRRv2PWfJKTh8n6BvOq1RaH/j1HTUCa+HB/m3tCgcBa
27r2W2MPjk3iB5JCTFl3PcF4x6ZqMF8iUCVasCnYptbTxQBeTL7ZY/WM3SfoRMRZ
I+ECxp9W+lOVi4cAEQEAAbQgZGVsdGF6dWx1IDxkZWx0YXp1bHVAZ29vZ2xlLmNv
bT65AY0EYGOOnwEMALasfY3MGi6RSX725SXYqqKaQDCqYbRaWKnSsFqNm7xC58Ib
HDgV8vG9VGATTLNj9WfJdPYS9dRTvQ4epVYfsBgtBkB0auNL/aAZ0+yNqtt+nh5b
TTeWricjAbljmtHHzVK1UQZV1ZBYJt0+oH3Zd143qKoKyRjSWLrt87h+wF54IFIJ
p6H+nlqmi2Z/vdR95Qrsh9BuYWMoHZcKcWgn3cOOdcmTvDzCBgSBw7lzV5qcyo8N
0fgpw17xrAqtFF0yGVmlpE+4GjRe34pDUzZstcS0lkj4uaEKalzr60gidv/UDLuu
xT5MkrK+xTpxlrODmsUkSZjm7xB1XXJ7qz/0foNzjbwksywE5Y3DFRh7YOH4jPIs
jgg3m3AlxUEwSG+PAod6lEj0JFyQOybqsLybB1U4j+66jZbxLLUHmHNUSV9ukXaI
zvVdTxxg/mJv0fCkD6+r++bAv0t3YK0t0VZmsKHSyMJp5uROS+mFxXCtUQcs6y5l
PFmLPwcvFVWdc6thEQARAQABiQG8BBgBCgAmFiEEVgU87boX4GXef7l766jpexUI
biQFAmBjjp8CGwwFCQPCZwAACgkQ66jpexUIbiSNywv/V5hK4Z3BnkvbJX8vhGAE
9xv0j3FOfQ1/k7DN2Z2ZjiYBJnDi6NpJLfPLOZBZII7ALyLWYJFm8EQSvwdQiaGq
RIGAaXvvB0NF3HkE7K+Qcifeqd6nb0do6bwbylaOTicxE2Jkx6yX2Lo/xz+MFNNi
/qHJ3wssCj+HVpmZYUEmgXdMav+cSsTjE576mw1LE/mRwAs72JX6lFMX9KTYD98W
+YZ8JBMqlNp7o17U7im62VhV9wF4wsX2FwargdsS11lYFay8uOemaby/ldMRlZlo
xI5Qi3anytqM9IGziB6uD8hJFEelk3nV8dfwvKC3zvBJiVvKrnLXSjXu82GerN7a
rY9Y5I644pxHfZXDpEmOYfWbvd7xzeWFL6HfY5UvFBxSBmBz6KYFNYUWoBl/oZP4
HEsh53Tu/7Z6OZYhnu2H7S/g89fccGZ5CSf7S1CT9jxbv7gIHTy5NbwiXC4b84DI
3B5ygD/qBV+GV98KiBDXFqq3I+dm+YjuK7lklzNKGLdu
=ceyA
-----END PGP PUBLIC KEY BLOCK-----
pub ECEAC3B11AD0E0A0
uid Priyanka <prigupta@adobe.com>
@ -3657,6 +3721,51 @@ WZQ/Q06arxcc0Nq2GaDkF3ts
=hBX9
-----END PGP PUBLIC KEY BLOCK-----
pub 3132F65CE170BB42
uid SpongePowered (Code Signing) <staff@spongepowered.org>
sub 9861EF2306DFBAC3
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
0A==
=Zm9Y
-----END PGP PUBLIC KEY BLOCK-----
pub 3595395EB3D8E1BA
uid Ralph Goers (CODE SIGNING KEY) <rgoers@apache.org>

View File

@ -26,13 +26,17 @@
<trusted-key id="0B1B71E813C226033B16D8C5F0D228D8FF31B515" group="^io[.]zipkin($|([.].*))" regex="true"/>
<trusted-key id="0B743A794876D3C78AB542A118D239B1CBCD2236" group="org.glassfish.jersey" name="jersey-bom"/>
<trusted-key id="0CC641C3A62453AB390066C4A41F13C999945293" group="commons-collections" name="commons-collections" version="3.2.2"/>
<trusted-key id="0CDE80149711EB46DFF17AE421A24B3F8B0F594A" group="org.apache" name="apache" version="16"/>
<trusted-key id="0CFA413799E2464C7D7E26220A4B343F2A55FDAE" group="com.h2database" name="h2" version="2.3.232"/>
<trusted-key id="0D35D3F60078655126908E8AF3D1600878E85A3D" group="io.netty" name="netty-bom"/>
<trusted-key id="0E0CA56D354132B5E646C25F49A1796B9B494CB8" group="org.opensaml"/>
<trusted-key id="0E9BD9062B021BBA50F41EEB9549F6CB1E679A56" group="org.locationtech.jts"/>
<trusted-key id="10F3C7A02ECA55E502BADCF3991EFB94DB91127D" group="org.ow2" name="ow2" version="1.5.1"/>
<trusted-key id="1452F35849B50750F6A3BBB4B54011358B352F85" group="org.hibernate.orm" name="hibernate-core" version="6.6.4.Final"/>
<trusted-key id="147B691A19097624902F4EA9689CBE64F4BC997F" group="org.mockito"/>
<trusted-key id="190D5A957FF22273E601F7A7C92C5FEC70161C62" group="org.apache" name="apache" version="18"/>
<trusted-key id="19BEAB2D799C020F17C69126B16698A4ADF4D638" group="org.checkerframework" name="checker-qual"/>
<trusted-key id="1AA8CF92D409A73393D0B736BFF2EE42C8282E76" group="org.apache.activemq" name="activemq-bom" version="6.1.4"/>
<trusted-key id="1D04A424F505394DBED15D451D0690E353BE126D" group="net.minidev"/>
<trusted-key id="1D2C7EF8ADA0F794B58C7C63436902AF59EDF60E" group="dev.equo.ide" name="solstice" version="1.8.1"/>
<trusted-key id="20FC6EC5F628F0EB66F157B8DC97B815CAC4E847" group="io.github.pixee" name="java-security-toolkit" version="1.2.1"/>
@ -42,6 +46,7 @@
<trusted-key id="28417C95E8906D108392822354A43F3254868410" group="org.apache.activemq"/>
<trusted-key id="2B1DD4CE9223D4E19C73531E5657B51F13E59DBE" group="com.unboundid.product.scim2"/>
<trusted-key id="2B34821418CF19CF1F2A8352953E02E4F573B46F" group="jakarta.platform"/>
<trusted-key id="2BCBDD0F23EA1CAFCC11D4860374CF2E8DD1BDFD" group="net.java"/>
<trusted-key id="2DB4F1EF0FA761ECC4EA935C86FDC7E2A11262CB">
<trusting group="commons-beanutils"/>
<trusting group="commons-codec"/>
@ -50,13 +55,17 @@
<trusting group="org.apache.commons"/>
<trusting group="xml-apis"/>
</trusted-key>
<trusted-key id="2DC48CBB4352B4953AF6F803D433B437192A0FD1" group="com.datastax.oss" name="java-driver-bom" version="4.15.0"/>
<trusted-key id="2E3A1AFFE42B5F53AF19F780BCF4173966770193" group="org.jetbrains" name="annotations" version="13.0"/>
<trusted-key id="2FC53E6B1F681184F4CCD637F5C81DE10A0B8ECC" group="org.yaml" name="snakeyaml" version="2.3"/>
<trusted-key id="3262A061C42FC4C7BBB5C25C1CF0293FA53CA458" group="org.apache.tomcat.embed"/>
<trusted-key id="33FD4BFD33554634053D73C0C2148900BCD3C2AF" group="org.jetbrains" name="annotations" version="24.0.1"/>
<trusted-key id="34441E504A937F43EB0DAEF96A65176A0FB1CD0B" group="org.apache.groovy" name="groovy-bom"/>
<trusted-key id="3690C240CE51B4670D30AD1C38EE757D69184620" group="org.tukaani" name="xz" version="1.9"/>
<trusted-key id="3750777B9C4B7D233B9D0C40307A96FBA0292109" group="org.postgresql" name="postgresql"/>
<trusted-key id="3750777B9C4B7D233B9D0C40307A96FBA0292109">
<trusting group="org.postgresql" name="postgresql" version="42.7.4"/>
<trusting group="org.postgresql" name="postgresql" version="42.7.5"/>
</trusted-key>
<trusted-key id="38319E05F62674572CDF886170B2EBE96C112CC9" group="org.cryptacular" name="cryptacular" version="1.2.5"/>
<trusted-key id="3E61D8C230332482009D7F0EDB901B24CAD38BC4" group="io.swagger.core.v3"/>
<trusted-key id="3F05DDA9F317301E927136D417A27CE7A60FF5F0" group="io.opentelemetry" name="opentelemetry-bom"/>
@ -65,7 +74,9 @@
<trusting group="jakarta.enterprise"/>
<trusting group="jakarta.inject"/>
</trusted-key>
<trusted-key id="41B962CF9AA2A26FF1F234D2A6144824624A3CBA" group="io.leangen.geantyref" name="geantyref" version="1.3.11"/>
<trusted-key id="41D266DB4427983A1A4AFB0C3684155E9365C30E" group="com.jayway.jsonpath" name="json-path" version="2.9.0"/>
<trusted-key id="44FBDBBC1A00FE414F1C1873586654072EAD6677" group="org.sonatype.oss" name="oss-parent" version="9"/>
<trusted-key id="453EA31328DE7D8AAA55AD4ED56C721C1CFF1424" group="^com[.]twelvemonkeys($|([.].*))" regex="true"/>
<trusted-key id="475F3B8E59E6E63AA78067482C7B12F2A511E325" group="org.slf4j"/>
<trusted-key id="477E62A656AD5475A1882855C809CA3C41BA6E96" group="jakarta.validation" name="jakarta.validation-api" version="3.0.2"/>
@ -79,7 +90,13 @@
<trusting group="io.spring.gradle"/>
<trusting group="^org[.]springframework($|([.].*))" regex="true"/>
</trusted-key>
<trusted-key id="4F7E32D440EF90A83011A8FC6425559C47CC79C4" group="javax.activation"/>
<trusted-key id="498AAC354AA5CB36FAAB7608B6E83A2D2E447E56" group="org.apache.cassandra" name="java-driver-bom" version="4.18.1"/>
<trusted-key id="4F7E32D440EF90A83011A8FC6425559C47CC79C4">
<trusting group="com.sun.activation" name="all" version="1.2.0"/>
<trusting group="javax.activation"/>
</trusted-key>
<trusted-key id="53C935821AA6A755BD337DB53595395EB3D8E1BA" group="org.apache.logging.log4j" name="log4j-bom" version="2.20.0"/>
<trusted-key id="56053CEDBA17E065DE7FB97BEBA8E97B15086E24" group="com.google.errorprone"/>
<trusted-key id="5719E50EAC5A4B1DD390B72C2A742740E08E7F8D" group="org.antlr"/>
<trusted-key id="57312C37B064EE0FDAB0130490D5CE79E1DE6A2C" group="com.querydsl" name="querydsl-bom"/>
<trusted-key id="5989BAF76217B843D66BE55B2D0E1FB8FE4B68B4" group="^org[.]eclipse[.]jetty($|([.].*))" regex="true"/>
@ -89,7 +106,9 @@
<trusting group="ch.qos.logback"/>
<trusting group="org.slf4j"/>
</trusted-key>
<trusted-key id="694621A7227D8D5289699830ABE9F3126BB741C1" group="com.google.guava" name="guava-parent" version="26.0-android"/>
<trusted-key id="6DD3B8C64EF75253BEB2C53AD908A43FB7EC07AC" group="jakarta.activation" name="jakarta.activation-api" version="2.1.3"/>
<trusted-key id="6E13156C0EE653F0B984663AB95BBD3FA43C4492" group="org.apache" name="apache" version="3"/>
<trusted-key id="6F538074CCEBF35F28AF9B066A0975F8B1127B83" group="org.jetbrains.kotlin"/>
<trusted-key id="70CD19BFD9F6C330027D6F260315BFB7970A144F" group="javax.xml.bind"/>
<trusted-key id="71EBF1CA4125B10AAB1E17CDB7DC526C17E3608B" group="jakarta.persistence" name="jakarta.persistence-api" version="3.1.0"/>
@ -99,6 +118,7 @@
<trusted-key id="7A1D848E7C2AF85EEBA69C99E7BF252CF360097E" group="org.latencyutils" name="LatencyUtils" version="2.0.3"/>
<trusted-key id="7B121B76A7ED6CE6E60AD51784E913A8E3A748C0" group="org.bouncycastle"/>
<trusted-key id="7C669810892CBD3148FA92995B05CCDE140C2876" group="org.eclipse.jgit"/>
<trusted-key id="808D78B17A5A2D7C3668E31FBFFC9B54721244AD" group="org.apache.commons" name="commons-parent" version="39"/>
<trusted-key id="80F6D6B0D90C6747753344CAB5A9E81B565E89E0" group="org.tomlj" name="tomlj" version="1.0.0"/>
<trusted-key id="81BE0C38ACE8AEDC7735A05F4C2AFF633F3A7223" group="org.seleniumhq.selenium" name="selenium-bom"/>
<trusted-key id="81CCDC71C7D61C179B27002D6A9FBE152D4C64D1" group="org.openjfx"/>
@ -111,9 +131,13 @@
</trusted-key>
<trusted-key id="84789D24DF77A32433CE1F079EB80E92EB2135B1" group="org.apache" name="apache"/>
<trusted-key id="8756C4F765C9AC3CB6B85D62379CE192D401AB61" group="com.diffplug.durian"/>
<trusted-key id="894F14D98D7F20D5E82645E3DFE102108BF9381F" group="org.hibernate.search" name="hibernate-search-bom" version="7.1.2.Final"/>
<trusted-key id="9141D1D81880A49AAD06FC1F3132F65CE170BB42" group="org.spongepowered"/>
<trusted-key id="94976E17E18DD3201447286954963C3E875A56AE" group="io.smallrye"/>
<trusted-key id="9579802DC3E15DE9C389239FC0D48A119CE7EE7B" group="com.zaxxer" name="HikariCP" version="5.1.0"/>
<trusted-key id="9790B1EC52577244529621F38C77ED250E495230" group="com.bucket4j" name="bucket4j_jdk17-core" version="8.14.0"/>
<trusted-key id="982C26A0C156D986CC2AD19E3FBA8E8E719022D7" group="org.jboss" name="jboss-parent" version="39"/>
<trusted-key id="9B32CBC0F3F6BA4C13D611FC21871D2A9AB66A31" group="io.rsocket" name="rsocket-bom" version="1.1.3"/>
<trusted-key id="9E3044071B758EBCB7E45673700E4F39BC05364B" group="org.eclipse.platform" name="org.eclipse.osgi" version="3.18.500"/>
<trusted-key id="A41A5960555F8CBBC7D8B2D7787F3A057B828D36" group="org.springdoc"/>
<trusted-key id="A5BD02B93E7A40482EB1D66A5F69AD087600B22C" group="org.ow2.asm"/>
@ -124,14 +148,18 @@
<trusted-key id="A9789342F598AD5B1175EF357EB97D110DFADD60" group="com.googlecode.concurrent-trees" name="concurrent-trees" version="2.6.1"/>
<trusted-key id="AA70C7C433D501636392EC02153E7A3C2B4E5118" group="org.eclipse.ee4j" name="project"/>
<trusted-key id="AB1DC33940689C44669107094989E0E939C2999B" group="com.opencsv" name="opencsv" version="5.10"/>
<trusted-key id="B1F250C1F371EBF0E31E86E30E31BBB30C940D01" group="com.posthog.java" name="posthog" version="1.1.1"/>
<trusted-key id="B6E73D84EA4FCC47166087253FAAD2CD5ECBB314" group="org.apache.commons" name="commons-parent"/>
<trusted-key id="BA926F64CA647B6D853A38672E2010F8A7FF4A41" group="org.apache" name="apache" version="7"/>
<trusted-key id="BB785E0400E71390977E4D1ADF3CC7C64D56297B" group="jakarta.interceptor" name="jakarta.interceptor-api" version="2.1.0"/>
<trusted-key id="BCA1F17506AF088F3A964A9C0459A2B383ED8C11" group="org.eclipse.angus"/>
<trusted-key id="BDB5FA4FE719D787FB3D3197F6D4A1D411E9D1AE" group="^com[.]google($|([.].*))" regex="true"/>
<trusted-key id="BE685132AFD2740D9095F9040CC0B712FEE75827" group="org.assertj"/>
<trusted-key id="C1D1ADA83198AA7FEAD102483FFE64C7506FCCC9" group="com.coveo" name="saml-client" version="5.0.0"/>
<trusted-key id="C663D2F64DA2CA09DB28D9ABD3FA67D522C55256" group="org.apache.pulsar" name="pulsar-bom" version="3.3.3"/>
<trusted-key id="C7BE5BCC9FEC15518CFDA882B0F3710FA64900E7" group="com.google.code.gson"/>
<trusted-key id="C89074FC8BE681B7C7EAAB6E4C5EED3C53B75933" group="org.skyscreamer" name="jsonassert" version="1.5.3"/>
<trusted-key id="CA62ED130E4053944406DF640181B45EA58677BC" group="org.apache.logging" name="logging-parent" version="7"/>
<trusted-key id="CC57399D74CD7E4768ED6FA4CA62973FBF0451C0" group="com.vaadin.external.google" name="android-json" version="0.0.20131108.vaadin1"/>
<trusted-key id="CD5464315F0B98C77E6E8ECD9DAADC1C9FCC82D0" group="commons-cli" name="commons-cli" version="1.4"/>
<trusted-key id="CE3285F320685193D11FEA01F6CE9695C9318406" group="com.google.zxing"/>
@ -161,6 +189,7 @@
<trusted-key id="EE0CA873074092F806F59B65D364ABAA39A47320" group="^com[.]google($|([.].*))" regex="true"/>
<trusted-key id="EED29BAB8D4FD882D62308CD72D1B04BC7E6AA04" group="me.friwi"/>
<trusted-key id="EF5214AD654CD05F0DA91609ECEAC3B11AD0E0A0" group="com.adobe.xmp" name="xmpcore" version="6.1.11"/>
<trusted-key id="F046369B06B761AC86D9849F71B329993BFFCFDD" group="com.oracle.database.jdbc" name="ojdbc-bom" version="21.9.0.0"/>
<trusted-key id="F0E31196852A34F8855710BD4A6CE7EBC7F4F54B" group="io.prometheus"/>
<trusted-key id="F1232CDCD94176E7FBA9CFE289A2C76A5EE16E57" group="technology.tabula" name="tabula" version="1.0.5"/>
<trusted-key id="F3184BCD55F4D016E30D4C9BF42E87F9665015C9" group="org.jsoup" name="jsoup" version="1.15.4"/>
@ -830,12 +859,12 @@
<sha256 value="616394c5a55cf67ff280ed6976ea7f3316ab09d44c0e29fa20b66acb290ac9a5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.posthog.java" name="posthog" version="1.2.0">
<artifact name="posthog-1.2.0.jar">
<sha256 value="827101003d85f658b5caac0f238210ff248486347ea9549dea4bc13c759f61aa" origin="Generated by Gradle"/>
<component group="com.posthog.java" name="posthog" version="1.1.1">
<artifact name="posthog-1.1.1.jar">
<sha256 value="651e2a8736854ed5dcd7e806ead96d47d92a184adc20ad17b1c21210228c7519" origin="Generated by Gradle"/>
</artifact>
<artifact name="posthog-1.2.0.pom">
<sha256 value="608a80275c6e15d9c827b8bfe51670d0b0aa8f2ea3b20779c53dafa241684cba" origin="Generated by Gradle"/>
<artifact name="posthog-1.1.1.pom">
<sha256 value="a23e9064a58224ca6ecb7905db03150e7704d31719ff236c711c54abcd63d3cd" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.querydsl" name="querydsl-bom" version="5.0.0">
@ -1282,12 +1311,12 @@
<sha256 value="63d96941eb44df9c90d2adb2ad8c3f699c2e065e707045c5daf713fca52bcfca" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="commons-logging" name="commons-logging" version="1.3.4">
<artifact name="commons-logging-1.3.4.jar">
<sha256 value="bc2dfe32f1ef06509e6a065144c1adf7b420eabf11a87f30bd127f8faa332016" origin="Generated by Gradle"/>
<component group="commons-logging" name="commons-logging" version="1.3.3">
<artifact name="commons-logging-1.3.3.jar">
<sha256 value="5828f96c09d886f9b1a0993c7804b27cf4fcec8534517164f5137ac8b67ea9b9" origin="Generated by Gradle"/>
</artifact>
<artifact name="commons-logging-1.3.4.pom">
<sha256 value="d4bda34892aaccbf4fad33fc323a8aa907ef9d79984659da24944c0a86bf0865" origin="Generated by Gradle"/>
<artifact name="commons-logging-1.3.3.pom">
<sha256 value="125d6142eac3f774440ba702c05f28f9e098c52d10712ae11496acb77106b3ba" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="dev.equo.ide" name="solstice" version="1.8.1">
@ -1323,7 +1352,7 @@
</component>
<component group="io.dropwizard.metrics" name="metrics-bom" version="4.2.25">
<artifact name="metrics-bom-4.2.25.pom">
<sha256 value="825ad37b8380f992b515050bbd95452f85466feae7b856d5c150d4e5f716a8e9" origin="Generated by Gradle"/>
<sha256 value="825ad37b8380f992b515050bbd95452f85466feae7b856d5c150d4e5f716a8e9" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="io.dropwizard.metrics" name="metrics-core" version="4.2.25">
@ -1346,7 +1375,7 @@
</component>
<component group="io.dropwizard.metrics" name="metrics-parent" version="4.2.25">
<artifact name="metrics-parent-4.2.25.pom">
<sha256 value="df7b6371f9b15698e123d9861f2099ca32c9ec966d9f0c60755a2a34ccbfabc2" origin="Generated by Gradle"/>
<sha256 value="df7b6371f9b15698e123d9861f2099ca32c9ec966d9f0c60755a2a34ccbfabc2" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="io.github.pixee" name="java-security-toolkit" version="1.2.1">
@ -1869,7 +1898,7 @@
<component group="net.shibboleth" name="parent" version="11.3.5">
<artifact name="parent-11.3.5.pom">
<pgp value="0E0CA56D354132B5E646C25F49A1796B9B494CB8"/>
<sha256 value="7a24e2700485eea087370f1dca6fe0291d7893d38c11aabfe977784fd93b808c" origin="Generated by Gradle"/>
<sha256 value="7a24e2700485eea087370f1dca6fe0291d7893d38c11aabfe977784fd93b808c" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="net.shibboleth" name="parent" version="11.3.7">
@ -2091,11 +2120,6 @@
<sha256 value="95b7be70f316ae4ca22f6fbdd08de2182e87cd874a650de7c3d3386a747a82a3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-parent" version="72">
<artifact name="commons-parent-72.pom">
<sha256 value="4345debfc767b1aeac68abdd72fc67d18b521d4b390372a11b63ff0c586b2320" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-parent" version="73">
<artifact name="commons-parent-73.pom">
<sha256 value="4ed44560b07f8448479dfd1e83a422ba4e83e60b36e51b2871ac502a6d5c1bea" origin="Generated by Gradle"/>
@ -2261,12 +2285,12 @@
<sha256 value="635e52e3474e7f4dc30d2ccbcb68a163888395e3c252961275d04e3db5f6e230" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pdfbox" name="fontbox" version="3.0.4">
<artifact name="fontbox-3.0.4.jar">
<sha256 value="2deec6232f5d6d3b31276592d31680ae9722af57d24cb0f76da70e2ba0e99e12" origin="Generated by Gradle"/>
<component group="org.apache.pdfbox" name="fontbox" version="3.0.3">
<artifact name="fontbox-3.0.3.jar">
<sha256 value="65690c3f39b04a14d12c17f4998c15186ce877d3e2ec222c708577e3cc028030" origin="Generated by Gradle"/>
</artifact>
<artifact name="fontbox-3.0.4.pom">
<sha256 value="f0ccc330e9b20d89578a0a8702b47a399bcd6288c2386d74ffab8f8e302844e8" origin="Generated by Gradle"/>
<artifact name="fontbox-3.0.3.pom">
<sha256 value="b2293e503aa77043061150f884683d7f614ccf5163be2d0f052ca29f3c7677e2" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pdfbox" name="jbig2-imageio" version="3.0.4">
@ -2277,41 +2301,41 @@
<sha256 value="28ea7c4ac92e0985f796a8bc6890a7bef8926707adadfd1e2c856c9b0be1a38b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pdfbox" name="pdfbox" version="3.0.4">
<artifact name="pdfbox-3.0.4.jar">
<sha256 value="09a0ff27d6f84a1dc40060cb0a01decf2ad4ef91c36bc91b9836c254be8aae45" origin="Generated by Gradle"/>
<component group="org.apache.pdfbox" name="pdfbox" version="3.0.3">
<artifact name="pdfbox-3.0.3.jar">
<sha256 value="5be38d2ec81691b05d535eb720de4dc566c5d07e5a04731fa00668d153a8b4a6" origin="Generated by Gradle"/>
</artifact>
<artifact name="pdfbox-3.0.4.pom">
<sha256 value="d3df032df2bdd234fe37030efac3576ba623fc97f5111354c4c52ad7775f90e4" origin="Generated by Gradle"/>
<artifact name="pdfbox-3.0.3.pom">
<sha256 value="be0895f6b2c20f311d6235c96a6fd2aac102b31904d3f4c39ea5259775b07008" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pdfbox" name="pdfbox-io" version="3.0.4">
<artifact name="pdfbox-io-3.0.4.jar">
<sha256 value="7a9d4746f2e13a1e22f4efe47fbaf999763caea41748535af93a01eedc50f554" origin="Generated by Gradle"/>
<component group="org.apache.pdfbox" name="pdfbox-io" version="3.0.3">
<artifact name="pdfbox-io-3.0.3.jar">
<sha256 value="123ea3187b497c54e661d50c3c867479bf77668ff450e50710c658f2bb4687ba" origin="Generated by Gradle"/>
</artifact>
<artifact name="pdfbox-io-3.0.4.pom">
<sha256 value="60b511757ef7ed3048bf82c7d8296f71d0bc470020118433ab3b3e3840bf8ea5" origin="Generated by Gradle"/>
<artifact name="pdfbox-io-3.0.3.pom">
<sha256 value="11701bb8c5a735a4b3140f73ae833a281cea09e3bc3f9f3791b9a97a745e90d4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pdfbox" name="pdfbox-parent" version="3.0.4">
<artifact name="pdfbox-parent-3.0.4.pom">
<sha256 value="c398fefb351ecff99311808d7ed5346e71f356b1134bd73a2504cb81707db451" origin="Generated by Gradle"/>
<component group="org.apache.pdfbox" name="pdfbox-parent" version="3.0.3">
<artifact name="pdfbox-parent-3.0.3.pom">
<sha256 value="c865e1ceff09ab52b087e7260c4f15d36e5b5b8be4ffe20446faa40a2ca0bdcc" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pdfbox" name="preflight" version="3.0.4">
<artifact name="preflight-3.0.4.jar">
<sha256 value="bf4691d4734df4914ed53cc68edea2fd9ea9a68d08ca187ba074e2a80d860e6e" origin="Generated by Gradle"/>
<component group="org.apache.pdfbox" name="preflight" version="3.0.3">
<artifact name="preflight-3.0.3.jar">
<sha256 value="0ac90829a97c3bdce233457fa62770cb50e403e7828cc537c635fdaa1c06f5c7" origin="Generated by Gradle"/>
</artifact>
<artifact name="preflight-3.0.4.pom">
<sha256 value="bb371d90444e604341e67fbbf0633e64114efb38b8c905779a6ac5e4be5704ac" origin="Generated by Gradle"/>
<artifact name="preflight-3.0.3.pom">
<sha256 value="31a45f38ca6c95bb46f19544ef346ab34baa9abe57a9de874b0b0b239ed702d0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pdfbox" name="xmpbox" version="3.0.4">
<artifact name="xmpbox-3.0.4.jar">
<sha256 value="d0af3fd7222fb3e18372a28ef7a98595a3f7d45e0cf5ad30f917ad8612c1ddbb" origin="Generated by Gradle"/>
<component group="org.apache.pdfbox" name="xmpbox" version="3.0.3">
<artifact name="xmpbox-3.0.3.jar">
<sha256 value="5fba39b3388ce4a3a77fa00b09c42963e670e08204faa7ecbf361e56b43f4c08" origin="Generated by Gradle"/>
</artifact>
<artifact name="xmpbox-3.0.4.pom">
<sha256 value="0e2eae71756fc3521518086e03177ba8a16d854da7b842b4556431ddb95eb6be" origin="Generated by Gradle"/>
<artifact name="xmpbox-3.0.3.pom">
<sha256 value="d10a16e7c44ac4c74ac9d9b580f073f9576ce43c579f24b4550716d076b60a17" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.pulsar" name="pulsar-bom" version="3.3.3">
@ -2525,14 +2549,6 @@
<sha256 value="9313bf53b3efd8aaca266eea8b96e307976b65c0b16510cc6f02319fbaebed43" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.checkerframework" name="checker-qual" version="3.48.3">
<artifact name="checker-qual-3.48.3.jar">
<sha256 value="443685b1b232803baaf803c15d6f5a425473c6f7b81c5f276dfcf93288e389a5" origin="Generated by Gradle"/>
</artifact>
<artifact name="checker-qual-3.48.3.module">
<sha256 value="127bbc5513e41ccfe6b3cb6faa7801423349a95414367acb7cf7629767549e59" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.commonmark" name="commonmark" version="0.24.0">
<artifact name="commonmark-0.24.0.jar">
<sha256 value="679338e0b7fc15c02d275d598654b01a149893bc28a87992e90123c8d06af25b" origin="Generated by Gradle"/>
@ -3416,7 +3432,7 @@
</component>
<component group="org.opensaml" name="opensaml-bom" version="4.3.0">
<artifact name="opensaml-bom-4.3.0.pom">
<sha256 value="4dfcc7cd96a2645c6e28df9f166f0e5b2b1a44aa109b3100cdb0ee17e01e02d2" origin="Generated by Gradle"/>
<sha256 value="4dfcc7cd96a2645c6e28df9f166f0e5b2b1a44aa109b3100cdb0ee17e01e02d2" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="org.opensaml" name="opensaml-core" version="4.3.2">
@ -3437,7 +3453,7 @@
</component>
<component group="org.opensaml" name="opensaml-parent" version="4.3.0">
<artifact name="opensaml-parent-4.3.0.pom">
<sha256 value="5e9db2f2dc3938835a76f5334997d79c8781511c8b68c1f6df6b384306900319" origin="Generated by Gradle"/>
<sha256 value="5e9db2f2dc3938835a76f5334997d79c8781511c8b68c1f6df6b384306900319" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="org.opensaml" name="opensaml-parent" version="4.3.2">
@ -3590,18 +3606,13 @@
</artifact>
</component>
<component group="org.postgresql" name="postgresql" version="42.7.4">
<artifact name="postgresql-42.7.4.jar">
<sha256 value="188976721ead8e8627eb6d8389d500dccc0c9bebd885268a3047180274a6031e" origin="Generated by Gradle"/>
</artifact>
<artifact name="postgresql-42.7.4.pom">
<sha256 value="ddfc1f093e5527af9b3d05a11beb09b4661f2c2b2ff337649a7369eea0cc71de" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.postgresql" name="postgresql" version="42.7.5">
<artifact name="postgresql-42.7.5.jar">
<sha256 value="69020b3bd20984543e817393f2e6c01a890ef2e37a77dd11d6d8508181d079ab" origin="Generated by Gradle"/>
</artifact>
<artifact name="postgresql-42.7.5.pom">
<sha256 value="141ea93fc185deb15d28fcfe3fea808af40189cf6912d68f316e868d7ceafe48" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.projectlombok" name="lombok" version="1.18.36">
<artifact name="lombok-1.18.36.jar">
<sha256 value="73b6b05b6a2d365b700bab08d30f94de9d336490bc0acce5b6181fef48cbf18e" origin="Generated by Gradle"/>
@ -3805,7 +3816,7 @@
<sha256 value="5ddd44ba297f3ddeada7815e476685318bd887559d3799aa70b75933b51fd504" origin="Generated by Gradle"/>
</artifact>
<artifact name="spring-framework-bom-5.3.34.pom">
<sha256 value="6d0616e2544d7115dc249817dd758a34dfa677329182b42e17542e133e55732d" origin="Generated by Gradle"/>
<sha256 value="6d0616e2544d7115dc249817dd758a34dfa677329182b42e17542e133e55732d" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="org.springframework" name="spring-framework-bom" version="5.3.39">

View File

@ -9,135 +9,200 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.List;
import org.simpleyaml.configuration.comments.CommentType;
import org.simpleyaml.configuration.file.YamlFile;
import org.simpleyaml.configuration.implementation.SimpleYamlImplementation;
import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions;
import java.util.*;
import lombok.extern.slf4j.Slf4j;
/**
* A naive, line-based approach to merging "settings.yml" with "settings.yml.template" while
* preserving exact whitespace, blank lines, and inline comments -- but we only rewrite the file if
* the merged content actually differs.
*/
@Slf4j
public class ConfigInitializer {
public void ensureConfigExists() throws IOException, URISyntaxException {
// Define the path to the external config directory
// 1) If settings file doesn't exist, create from template
Path destPath = Paths.get(InstallationPathConfig.getSettingsPath());
// Check if the file already exists
if (Files.notExists(destPath)) {
// Ensure the destination directory exists
Files.createDirectories(destPath.getParent());
// Copy the resource from classpath to the external directory
try (InputStream in =
getClass().getClassLoader().getResourceAsStream("settings.yml.template")) {
if (in != null) {
Files.copy(in, destPath);
} else {
if (in == null) {
throw new FileNotFoundException(
"Resource file not found: settings.yml.template");
}
Files.copy(in, destPath);
}
log.info("Created settings file from template");
} else {
// Define the path to the config settings file
// 2) Merge existing file with the template
Path settingsPath = Paths.get(InstallationPathConfig.getSettingsPath());
// Load the template resource
URL settingsTemplateResource =
getClass().getClassLoader().getResource("settings.yml.template");
if (settingsTemplateResource == null) {
URL templateResource = getClass().getClassLoader().getResource("settings.yml.template");
if (templateResource == null) {
throw new IOException("Resource not found: settings.yml.template");
}
// Create a temporary file to copy the resource content
// Copy template to a temp location so we can read lines
Path tempTemplatePath = Files.createTempFile("settings.yml", ".template");
try (InputStream in = settingsTemplateResource.openStream()) {
try (InputStream in = templateResource.openStream()) {
Files.copy(in, tempTemplatePath, StandardCopyOption.REPLACE_EXISTING);
}
final YamlFile settingsTemplateFile = new YamlFile(tempTemplatePath.toFile());
DumperOptions yamlOptionsSettingsTemplateFile =
((SimpleYamlImplementation) settingsTemplateFile.getImplementation())
.getDumperOptions();
yamlOptionsSettingsTemplateFile.setSplitLines(false);
settingsTemplateFile.loadWithComments();
// 2a) Read lines from both files
List<String> templateLines = Files.readAllLines(tempTemplatePath);
List<String> mainLines = Files.readAllLines(settingsPath);
final YamlFile settingsFile = new YamlFile(settingsPath.toFile());
DumperOptions yamlOptionsSettingsFile =
((SimpleYamlImplementation) settingsFile.getImplementation())
.getDumperOptions();
yamlOptionsSettingsFile.setSplitLines(false);
settingsFile.loadWithComments();
// 2b) Merge lines
List<String> mergedLines = mergeYamlLinesWithTemplate(templateLines, mainLines);
// Load headers and comments
String header = settingsTemplateFile.getHeader();
// Create a new file for temporary settings
final YamlFile tempSettingFile = new YamlFile(settingsPath.toFile());
DumperOptions yamlOptionsTempSettingFile =
((SimpleYamlImplementation) tempSettingFile.getImplementation())
.getDumperOptions();
yamlOptionsTempSettingFile.setSplitLines(false);
tempSettingFile.createNewFile(true);
tempSettingFile.setHeader(header);
// Get all keys from the template
List<String> keys =
Arrays.asList(settingsTemplateFile.getKeys(true).toArray(new String[0]));
for (String key : keys) {
if (!key.contains(".")) {
// Add blank lines and comments to specific sections
tempSettingFile
.path(key)
.comment(settingsTemplateFile.getComment(key))
.blankLine();
continue;
}
// Copy settings from the template to the settings.yml file
changeConfigItemFromCommentToKeyValue(
settingsTemplateFile, settingsFile, tempSettingFile, key);
// 2c) Only write if there's an actual difference
if (!mergedLines.equals(mainLines)) {
Files.write(settingsPath, mergedLines);
log.info("Settings file updated based on template changes.");
} else {
log.info("No changes detected; settings file left as-is.");
}
// Save the settings.yml file
tempSettingFile.save();
Files.deleteIfExists(tempTemplatePath);
}
// Create custom settings file if it doesn't exist
// 3) Ensure custom settings file exists
Path customSettingsPath = Paths.get(InstallationPathConfig.getCustomSettingsPath());
if (!Files.exists(customSettingsPath)) {
Files.createFile(customSettingsPath);
}
}
private void changeConfigItemFromCommentToKeyValue(
final YamlFile settingsTemplateFile,
final YamlFile settingsFile,
final YamlFile tempSettingFile,
String path) {
if (settingsFile.get(path) == null && settingsTemplateFile.get(path) != null) {
// If the key is only in the template, add it to the temporary settings with comments
tempSettingFile
.path(path)
.set(settingsTemplateFile.get(path))
.comment(settingsTemplateFile.getComment(path, CommentType.BLOCK))
.commentSide(settingsTemplateFile.getComment(path, CommentType.SIDE));
} else if (settingsFile.get(path) != null && settingsTemplateFile.get(path) != null) {
// If the key is in both, update the temporary settings with the main settings' value
// and comments
tempSettingFile
.path(path)
.set(settingsFile.get(path))
.comment(settingsTemplateFile.getComment(path, CommentType.BLOCK))
.commentSide(settingsTemplateFile.getComment(path, CommentType.SIDE));
} else {
// Log if the key is not found in both YAML files
log.info("Key not found in both YAML files: " + path);
/**
* Merge logic that: - Reads the template lines block-by-block (where a "block" = a key and all
* the lines that belong to it), - If the main file has that key, we keep the main file's block
* (preserving whitespace + inline comments). - Otherwise, we insert the template's block. - We
* also remove keys from main that no longer exist in the template.
*
* @param templateLines lines from settings.yml.template
* @param mainLines lines from the existing settings.yml
* @return merged lines
*/
private List<String> mergeYamlLinesWithTemplate(
List<String> templateLines, List<String> mainLines) {
// 1) Parse template lines into an ordered map: path -> Block
LinkedHashMap<String, Block> templateBlocks = parseYamlBlocks(templateLines);
// 2) Parse main lines into a map: path -> Block
LinkedHashMap<String, Block> mainBlocks = parseYamlBlocks(mainLines);
// 3) Build the final list by iterating template blocks in order
List<String> merged = new ArrayList<>();
for (Map.Entry<String, Block> entry : templateBlocks.entrySet()) {
String path = entry.getKey();
Block templateBlock = entry.getValue();
if (mainBlocks.containsKey(path)) {
// If main has the same block, prefer main's lines
merged.addAll(mainBlocks.get(path).lines);
} else {
// Otherwise, add the template block
merged.addAll(templateBlock.lines);
}
}
return merged;
}
/**
* Parse a list of lines into a map of "path -> Block" where "Block" is all lines that belong to
* that key (including subsequent indented lines). Very naive approach that may not work with
* advanced YAML.
*/
private LinkedHashMap<String, Block> parseYamlBlocks(List<String> lines) {
LinkedHashMap<String, Block> blocks = new LinkedHashMap<>();
Block currentBlock = null;
String currentPath = null;
for (String line : lines) {
if (isLikelyKeyLine(line)) {
// Found a new "key: ..." line
if (currentBlock != null && currentPath != null) {
blocks.put(currentPath, currentBlock);
}
currentBlock = new Block();
currentBlock.lines.add(line);
currentPath = computePathForLine(line);
} else {
// Continuation of current block (comments, blank lines, sub-lines)
if (currentBlock == null) {
// If file starts with comments/blank lines, treat as "header block" with path
// ""
currentBlock = new Block();
currentPath = "";
}
currentBlock.lines.add(line);
}
}
if (currentBlock != null && currentPath != null) {
blocks.put(currentPath, currentBlock);
}
return blocks;
}
/**
* Checks if the line is likely "key:" or "key: value", ignoring comments/blank. Skips lines
* starting with "-" or "#".
*/
private boolean isLikelyKeyLine(String line) {
String trimmed = line.trim();
if (trimmed.isEmpty() || trimmed.startsWith("#") || trimmed.startsWith("-")) {
return false;
}
int colonIdx = trimmed.indexOf(':');
return (colonIdx > 0); // someKey:
}
// For a line like "security: ", returns "security" or "security.enableLogin"
// by looking at indentation. Very naive.
private static final Deque<String> pathStack = new ArrayDeque<>();
private static int currentIndentLevel = 0;
private String computePathForLine(String line) {
// count leading spaces
int leadingSpaces = 0;
for (char c : line.toCharArray()) {
if (c == ' ') leadingSpaces++;
else break;
}
// assume 2 spaces = 1 indent
int indentLevel = leadingSpaces / 2;
String trimmed = line.trim();
int colonIdx = trimmed.indexOf(':');
String keyName = trimmed.substring(0, colonIdx).trim();
// pop stack until we match the new indent level
while (currentIndentLevel >= indentLevel && !pathStack.isEmpty()) {
pathStack.pop();
currentIndentLevel--;
}
// push the new key
pathStack.push(keyName);
currentIndentLevel = indentLevel;
// build path by reversing the stack
String[] arr = pathStack.toArray(new String[0]);
List<String> reversed = Arrays.asList(arr);
Collections.reverse(reversed);
return String.join(".", reversed);
}
/**
* Simple holder for the lines that comprise a "block" (i.e. a key and its subsequent lines).
*/
private static class Block {
List<String> lines = new ArrayList<>();
}
}

View File

@ -9,15 +9,17 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.MessageDigest;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.simpleyaml.configuration.file.YamlFile;
import org.simpleyaml.configuration.file.YamlFileWrapper;
import org.simpleyaml.configuration.implementation.SimpleYamlImplementation;
import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions;
import org.springframework.web.multipart.MultipartFile;
import com.fathzer.soft.javaluator.DoubleEvaluator;
@ -346,41 +348,208 @@ public class GeneralUtils {
public static void saveKeyToConfig(String id, String key, boolean autoGenerated)
throws IOException {
Path path =
Paths.get(
InstallationPathConfig
.getSettingsPath()); // Target the configs/settings.yml
final YamlFile settingsYml = new YamlFile(path.toFile());
DumperOptions yamlOptionssettingsYml =
((SimpleYamlImplementation) settingsYml.getImplementation()).getDumperOptions();
yamlOptionssettingsYml.setSplitLines(false);
settingsYml.loadWithComments();
YamlFileWrapper writer = settingsYml.path(id).set(key);
if (autoGenerated) {
writer.comment("# Automatically Generated Settings (Do Not Edit Directly)");
}
settingsYml.save();
doSaveKeyToConfig(id, (key == null ? "" : key), autoGenerated);
}
public static void saveKeyToConfig(String id, boolean key, boolean autoGenerated)
throws IOException {
Path path = Paths.get(InstallationPathConfig.getSettingsPath());
doSaveKeyToConfig(id, String.valueOf(key), autoGenerated);
}
final YamlFile settingsYml = new YamlFile(path.toFile());
DumperOptions yamlOptionssettingsYml =
((SimpleYamlImplementation) settingsYml.getImplementation()).getDumperOptions();
yamlOptionssettingsYml.setSplitLines(false);
/*------------------------------------------------------------------------*
* Internal Implementation Details *
*------------------------------------------------------------------------*/
settingsYml.loadWithComments();
YamlFileWrapper writer = settingsYml.path(id).set(key);
if (autoGenerated) {
writer.comment("# Automatically Generated Settings (Do Not Edit Directly)");
/**
* Actually performs the line-based update for the given path (e.g. "security.csrfDisabled") to
* a new string value (e.g. "true"), possibly marking it as auto-generated.
*/
private static void doSaveKeyToConfig(String fullPath, String newValue, boolean autoGenerated)
throws IOException {
// 1) Load the file (settings.yml)
Path settingsPath = Paths.get(InstallationPathConfig.getSettingsPath());
if (!Files.exists(settingsPath)) {
log.warn("Settings file not found at {}, creating a new empty file...", settingsPath);
Files.createDirectories(settingsPath.getParent());
Files.createFile(settingsPath);
}
settingsYml.save();
List<String> lines = Files.readAllLines(settingsPath);
// 2) Build a map of "nestedKeyPath -> lineIndex" by parsing indentation
// Also track each line's indentation so we can preserve it when rewriting.
Map<String, LineInfo> pathToLine = parseNestedYamlKeys(lines);
// 3) If the path is found, rewrite its line. Else, append at the bottom (no indentation).
boolean changed = false;
if (pathToLine.containsKey(fullPath)) {
// Rewrite existing line
LineInfo info = pathToLine.get(fullPath);
String oldLine = lines.get(info.lineIndex);
String newLine =
rewriteLine(oldLine, info.indentSpaces, fullPath, newValue, autoGenerated);
if (!newLine.equals(oldLine)) {
lines.set(info.lineIndex, newLine);
changed = true;
}
} else {
// Append a new line at the bottom, with zero indentation
String appended = fullPath + ": " + newValue;
if (autoGenerated) {
appended += " # Automatically Generated Settings (Do Not Edit Directly)";
}
lines.add(appended);
changed = true;
}
// 4) If changed, write back to file
if (changed) {
Files.write(settingsPath, lines);
log.info(
"Updated '{}' to '{}' (autoGenerated={}) in {}",
fullPath,
newValue,
autoGenerated,
settingsPath);
} else {
log.info("No changes for '{}' (already set to '{}').", fullPath, newValue);
}
}
/** A small record-like class that holds: - lineIndex - indentSpaces */
private static class LineInfo {
int lineIndex;
int indentSpaces;
public LineInfo(int lineIndex, int indentSpaces) {
this.lineIndex = lineIndex;
this.indentSpaces = indentSpaces;
}
}
/**
* Parse the YAML lines to build a map: "full.nested.key" -> (lineIndex, indentSpaces). We do a
* naive indentation-based path stacking: - 2 spaces = 1 indent level - lines that start with
* fewer or equal indentation pop the stack - lines that look like "key:" or "key: value" cause
* a push
*/
private static Map<String, LineInfo> parseNestedYamlKeys(List<String> lines) {
Map<String, LineInfo> result = new HashMap<>();
// We'll maintain a stack of (keyName, indentLevel).
// Each line that looks like "myKey:" or "myKey: value" is a new "child" of the top of the
// stack if indent is deeper.
Deque<String> pathStack = new ArrayDeque<>();
Deque<Integer> indentStack = new ArrayDeque<>();
indentStack.push(-1); // sentinel
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
String trimmed = line.trim();
// skip blank lines, comment lines, or list items
if (trimmed.isEmpty() || trimmed.startsWith("#") || trimmed.startsWith("-")) {
continue;
}
// check if there's a colon
int colonIdx = trimmed.indexOf(':');
if (colonIdx <= 0) { // must have at least one char before ':'
continue;
}
// parse out key
String keyPart = trimmed.substring(0, colonIdx).trim();
if (keyPart.isEmpty()) {
continue;
}
// count leading spaces for indentation
int leadingSpaces = countLeadingSpaces(line);
int indentLevel = leadingSpaces / 2; // assume 2 spaces per level
// pop from stack until we get to a shallower indentation
while (indentStack.peek() != null && indentStack.peek() >= indentLevel) {
indentStack.pop();
pathStack.pop();
}
// push the new key
pathStack.push(keyPart);
indentStack.push(indentLevel);
// build the full path
String[] arr = pathStack.toArray(new String[0]);
List<String> reversed = Arrays.asList(arr);
Collections.reverse(reversed);
String fullPath = String.join(".", reversed);
// store line info
result.put(fullPath, new LineInfo(i, leadingSpaces));
}
return result;
}
/**
* Rewrite a single line to set a new value, preserving indentation and (optionally) the
* existing or auto-generated inline comment.
*
* <p>For example, oldLine might be: " csrfDisabled: false # set to 'true' to disable CSRF
* protection" newValue = "true" autoGenerated = false
*
* <p>We'll produce something like: " csrfDisabled: true # set to 'true' to disable CSRF
* protection"
*/
private static String rewriteLine(
String oldLine, int indentSpaces, String path, String newValue, boolean autoGenerated) {
// We'll keep the exact leading indentation (indentSpaces).
// Then "key: newValue". We'll try to preserve any existing inline comment unless
// autoGenerated is true.
// 1) Extract leading spaces from the old line (just in case they differ from indentSpaces).
int actualLeadingSpaces = countLeadingSpaces(oldLine);
String leading = oldLine.substring(0, actualLeadingSpaces);
// 2) Remove leading spaces from the rest
String trimmed = oldLine.substring(actualLeadingSpaces);
// 3) Check for existing comment
int hashIndex = trimmed.indexOf('#');
String lineWithoutComment =
(hashIndex >= 0) ? trimmed.substring(0, hashIndex).trim() : trimmed.trim();
String oldComment = (hashIndex >= 0) ? trimmed.substring(hashIndex).trim() : "";
// 4) Rebuild "key: newValue"
// The "key" here is everything before ':' in lineWithoutComment
int colonIdx = lineWithoutComment.indexOf(':');
String existingKey =
(colonIdx >= 0)
? lineWithoutComment.substring(0, colonIdx).trim()
: path; // fallback if line is malformed
StringBuilder sb = new StringBuilder();
sb.append(leading); // restore original leading spaces
// "key: newValue"
sb.append(existingKey).append(": ").append(newValue);
// 5) If autoGenerated, add/replace comment
if (autoGenerated) {
sb.append(" # Automatically Generated Settings (Do Not Edit Directly)");
} else {
// preserve the old comment if it exists
if (!oldComment.isEmpty()) {
sb.append(" ").append(oldComment);
}
}
return sb.toString();
}
private static int countLeadingSpaces(String line) {
int count = 0;
for (char c : line.toCharArray()) {
if (c == ' ') count++;
else break;
}
return count;
}
public static String generateMachineFingerprint() {