Compare commits

...

36 Commits

Author SHA1 Message Date
Reece Browne
70349fb7e3
remove legacy homepage (#3518)
# 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.
2025-05-20 12:08:20 +01:00
stirlingbot[bot]
bef86b44e4
Update 3rd Party Licenses (#3559)
Auto-generated by StirlingBot

Signed-off-by: stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-05-20 12:07:03 +01:00
Anthony Stirling
46cc2e05df
Add additional unit tests for utils and EE (#3557)
## Summary
- add tests for LicenseKeyChecker
- expand GeneralUtils coverage
- cover extra PdfUtils functionality
- merge PdfUtilsMoreTest into PdfUtilsTest

## Testing
- `./gradlew test --no-daemon`
- `./gradlew build spotlessApply --no-daemon`
2025-05-20 12:05:18 +01:00
Anthony Stirling
c8e25f4c5a
Fix TemplateResolver and LibreOfficeListener bugs (#3555)
## Summary
- log missing exceptions in FileFallbackTemplateResolver
- implement exists check for InputStreamTemplateResource
- use LISTENER_PORT constant when verifying LibreOffice listener

## Testing
- `./gradlew build --no-daemon`
- `./gradlew test --no-daemon`

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-20 12:02:26 +01:00
Anthony Stirling
218d21f07a
Update AGENTS guidelines (#3556)
## Summary
- clarify Codex contribution instructions
- remove `test.sh` reference and require `./gradlew build`
- add Developer Guide, AI note and translation policy

## Testing
- `./gradlew spotlessApply`
- `./gradlew build`
2025-05-20 12:02:10 +01:00
Anthony Stirling
9fe49c494d
Fix test compilation around pipeline processor (#3554)
## Summary
- allow tests to spy on PipelineProcessor web requests
- fix ResponseEntity usage in PipelineProcessorTest

## Testing
- `./gradlew test --offline` *(fails: No route to host while downloading
gradle-8.14-all.zip)*
2025-05-20 12:02:01 +01:00
dependabot[bot]
d59e39b4b6
Bump org.mockito:mockito-core from 5.11.0 to 5.17.0 (#3551)
Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito)
from 5.11.0 to 5.17.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mockito/mockito/releases">org.mockito:mockito-core's
releases</a>.</em></p>
<blockquote>
<h2>v5.17.0</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog
generated by <a
href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog
Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted
--></p>
<h4>5.17.0</h4>
<ul>
<li>2025-04-04 - <a
href="https://github.com/mockito/mockito/compare/v5.16.1...v5.17.0">7
commit(s)</a> by Adrian Roos, Andre Kurait, Jan Ouwens, Rafael
Winterhalter, Taeik Lim, Thach Le, Tim van der Lippe</li>
<li>Fixes <a
href="https://redirect.github.com/mockito/mockito/issues/3631">#3631</a>:
Fix broken banner image link [(<a
href="https://redirect.github.com/mockito/mockito/issues/3632">#3632</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3632">mockito/mockito#3632</a>)</li>
<li>Banner image is broken [(<a
href="https://redirect.github.com/mockito/mockito/issues/3631">#3631</a>)](<a
href="https://redirect.github.com/mockito/mockito/issues/3631">mockito/mockito#3631</a>)</li>
<li>Update exception message with mockito-inline [(<a
href="https://redirect.github.com/mockito/mockito/issues/3628">#3628</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3628">mockito/mockito#3628</a>)</li>
<li>Clarify structure of commit messages [(<a
href="https://redirect.github.com/mockito/mockito/issues/3626">#3626</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3626">mockito/mockito#3626</a>)</li>
<li>Fixes <a
href="https://redirect.github.com/mockito/mockito/issues/3622">#3622</a>:
MockitoExtension fails cleanup when aborted before setup [(<a
href="https://redirect.github.com/mockito/mockito/issues/3623">#3623</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3623">mockito/mockito#3623</a>)</li>
<li>MockitoExtension fails cleanup when aborted before setup [(<a
href="https://redirect.github.com/mockito/mockito/issues/3622">#3622</a>)](<a
href="https://redirect.github.com/mockito/mockito/issues/3622">mockito/mockito#3622</a>)</li>
<li>Since mockito-inline has been removed, the exception messages with
<code>mockito-inline</code> should be modified. [(<a
href="https://redirect.github.com/mockito/mockito/issues/3621">#3621</a>)](<a
href="https://redirect.github.com/mockito/mockito/issues/3621">mockito/mockito#3621</a>)</li>
<li>Fixes <a
href="https://redirect.github.com/mockito/mockito/issues/3171">#3171</a>:
Fall back to Throwable Location strategy on Android [(<a
href="https://redirect.github.com/mockito/mockito/issues/3619">#3619</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3619">mockito/mockito#3619</a>)</li>
<li>Fixes <a
href="https://redirect.github.com/mockito/mockito/issues/3615">#3615</a>
: broken links to javadoc.io [(<a
href="https://redirect.github.com/mockito/mockito/issues/3616">#3616</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3616">mockito/mockito#3616</a>)</li>
<li>Broken links to javadoc.io [(<a
href="https://redirect.github.com/mockito/mockito/issues/3615">#3615</a>)](<a
href="https://redirect.github.com/mockito/mockito/issues/3615">mockito/mockito#3615</a>)</li>
<li>Mocks are not working on particular devices after update Android SDK
from 33 to 34 [(<a
href="https://redirect.github.com/mockito/mockito/issues/3171">#3171</a>)](<a
href="https://redirect.github.com/mockito/mockito/issues/3171">mockito/mockito#3171</a>)</li>
</ul>
<h2>v5.16.1</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog
generated by <a
href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog
Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted
--></p>
<h4>5.16.1</h4>
<ul>
<li>2025-03-15 - <a
href="https://github.com/mockito/mockito/compare/v5.16.0...v5.16.1">3
commit(s)</a> by Adrian Roos, Jérôme Prinet, Rafael Winterhalter</li>
<li>Remove Arrays.asList from critical stubbing path in
GenericMetadataSu… [(<a
href="https://redirect.github.com/mockito/mockito/issues/3610">#3610</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3610">mockito/mockito#3610</a>)</li>
<li>Rework of injection strategy in the context of modules [(<a
href="https://redirect.github.com/mockito/mockito/issues/3608">#3608</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3608">mockito/mockito#3608</a>)</li>
<li>Adjust inline mocking snippet to allow task relocatability [(<a
href="https://redirect.github.com/mockito/mockito/issues/3606">#3606</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3606">mockito/mockito#3606</a>)</li>
<li>Inline mocking configuration snippet for Gradle should allow task
relocatability [(<a
href="https://redirect.github.com/mockito/mockito/issues/3605">#3605</a>)](<a
href="https://redirect.github.com/mockito/mockito/issues/3605">mockito/mockito#3605</a>)</li>
</ul>
<h2>v5.16.0</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog
generated by <a
href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog
Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted
--></p>
<h4>5.16.0</h4>
<ul>
<li>2025-03-03 - <a
href="https://github.com/mockito/mockito/compare/v5.15.2...v5.16.0">10
commit(s)</a> by Brice Dutheil, Rafael Winterhalter, TDL,
dependabot[bot]</li>
<li>Add support for including module-info in Mockito. [(<a
href="https://redirect.github.com/mockito/mockito/issues/3597">#3597</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3597">mockito/mockito#3597</a>)</li>
<li>Bump com.gradle.develocity from 3.19 to 3.19.1 [(<a
href="https://redirect.github.com/mockito/mockito/issues/3579">#3579</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3579">mockito/mockito#3579</a>)</li>
<li>Bump org.assertj:assertj-core from 3.27.2 to 3.27.3 [(<a
href="https://redirect.github.com/mockito/mockito/issues/3577">#3577</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3577">mockito/mockito#3577</a>)</li>
<li>Bump com.diffplug.spotless:spotless-plugin-gradle from 7.0.1 to
7.0.2 [(<a
href="https://redirect.github.com/mockito/mockito/issues/3574">#3574</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3574">mockito/mockito#3574</a>)</li>
<li>Bump com.diffplug.spotless:spotless-plugin-gradle from 6.25.0 to
7.0.1 [(<a
href="https://redirect.github.com/mockito/mockito/issues/3571">#3571</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3571">mockito/mockito#3571</a>)</li>
<li>Bump org.assertj:assertj-core from 3.27.1 to 3.27.2 [(<a
href="https://redirect.github.com/mockito/mockito/issues/3569">#3569</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3569">mockito/mockito#3569</a>)</li>
<li>Tweaks documentation on mockito agent config for maven [(<a
href="https://redirect.github.com/mockito/mockito/issues/3568">#3568</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3568">mockito/mockito#3568</a>)</li>
<li>Adds <code>--info</code> to diagnose
closeAndReleaseStagingRepositories issues [(<a
href="https://redirect.github.com/mockito/mockito/issues/3567">#3567</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3567">mockito/mockito#3567</a>)</li>
<li>Refine reflection when calling management factory [(<a
href="https://redirect.github.com/mockito/mockito/issues/3566">#3566</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3566">mockito/mockito#3566</a>)</li>
<li>Avoid warning when dynamic attach is enabled [(<a
href="https://redirect.github.com/mockito/mockito/issues/3551">#3551</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3551">mockito/mockito#3551</a>)</li>
</ul>
<h2>v5.15.2</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><em>Changelog
generated by <a
href="https://github.com/shipkit/shipkit-changelog">Shipkit Changelog
Gradle Plugin</a></em><!-- raw HTML omitted --><!-- raw HTML omitted
--></p>
<h4>5.15.2</h4>
<ul>
<li>2025-01-02 - <a
href="https://github.com/mockito/mockito/compare/v5.15.1...v5.15.2">2
commit(s)</a> by Brice Dutheil, dependabot[bot]</li>
<li>Fix javadoc publication [(<a
href="https://redirect.github.com/mockito/mockito/issues/3561">#3561</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3561">mockito/mockito#3561</a>)</li>
<li>Bump org.assertj:assertj-core from 3.27.0 to 3.27.1 [(<a
href="https://redirect.github.com/mockito/mockito/issues/3560">#3560</a>)](<a
href="https://redirect.github.com/mockito/mockito/pull/3560">mockito/mockito#3560</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7764992d12"><code>7764992</code></a>
Remove mention of <code>mockito-inline</code> from mockmaker exception
(<a
href="https://redirect.github.com/mockito/mockito/issues/3628">#3628</a>)</li>
<li><a
href="ee92ad4916"><code>ee92ad4</code></a>
Fix broken banner image link (<a
href="https://redirect.github.com/mockito/mockito/issues/3632">#3632</a>)</li>
<li><a
href="3edab52835"><code>3edab52</code></a>
Clarify structure of commit messages (<a
href="https://redirect.github.com/mockito/mockito/issues/3626">#3626</a>)</li>
<li><a
href="bfab74365e"><code>bfab743</code></a>
Fall back to Throwable Location strategy on Android (<a
href="https://redirect.github.com/mockito/mockito/issues/3619">#3619</a>)</li>
<li><a
href="4f469c830b"><code>4f469c8</code></a>
MockitoExtension fails cleanup when aborted before setup (<a
href="https://redirect.github.com/mockito/mockito/issues/3623">#3623</a>)</li>
<li><a
href="1764e62102"><code>1764e62</code></a>
Update links to javadoc.io (<a
href="https://redirect.github.com/mockito/mockito/issues/3616">#3616</a>)</li>
<li><a
href="1e029d767b"><code>1e029d7</code></a>
Add missing requirement to objenesis.</li>
<li><a
href="d000e63077"><code>d000e63</code></a>
Rework of injection strategy in the context of modules (<a
href="https://redirect.github.com/mockito/mockito/issues/3608">#3608</a>)</li>
<li><a
href="0215884a5e"><code>0215884</code></a>
Remove Arrays.asList from critical stubbing path in
GenericMetadataSupport (#...</li>
<li><a
href="d18503512b"><code>d185035</code></a>
Add reference to Gradle documentation on how to make task relocatable
(<a
href="https://redirect.github.com/mockito/mockito/issues/3606">#3606</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/mockito/mockito/compare/v5.11.0...v5.17.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.mockito:mockito-core&package-manager=gradle&previous-version=5.11.0&new-version=5.17.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 12:00:31 +01:00
dependabot[bot]
9514370cc3
Bump org.gradle.toolchains.foojay-resolver-convention from 0.10.0 to 1.0.0 (#3552)
Bumps org.gradle.toolchains.foojay-resolver-convention from 0.10.0 to
1.0.0.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.gradle.toolchains.foojay-resolver-convention&package-manager=gradle&previous-version=0.10.0&new-version=1.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:58:23 +01:00
dependabot[bot]
b9dd78ced6
Bump io.micrometer:micrometer-core from 1.14.7 to 1.15.0 (#3550)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer)
from 1.14.7 to 1.15.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/micrometer-metrics/micrometer/releases">io.micrometer:micrometer-core's
releases</a>.</em></p>
<blockquote>
<h2>1.15.0</h2>
<h2> New Features</h2>
<ul>
<li>Further enhancement to OtlpMetricsSender <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6025">#6025</a></li>
<li>Make Prometheus Metric and Label naming conventions consistent <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5923">#5923</a></li>
<li>Metrics for Executors.newVirtualThreadPerTaskExecutor() <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5488">#5488</a></li>
<li>Metrics for live virtual threads <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5950">#5950</a></li>
<li>More flexible OTLP per meter configuration <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6099">#6099</a></li>
<li>Prometheus/OpenMetrics <code>_created</code> timestamp <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/2625">#2625</a></li>
<li>Make jvm.classes.unloaded description generic <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5745">#5745</a></li>
<li>Use String.toLowerCase()/toUpperCase() with Locale.ROOT consistently
<a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5711">#5711</a></li>
<li>Use failWithActualExpectedAndMessage() where possible <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5696">#5696</a></li>
<li>Provide target host/port info in ObservationExecChainHandler when
HttpHostConnectException is thrown <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5615">#5615</a></li>
<li>Enable Gauge builders to take a subclass of Number <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5601">#5601</a></li>
<li>micrometer-observation-test support for assertions on events <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5576">#5576</a></li>
<li>Log delta count in addition to throughput in LoggingMeterRegistry <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5548">#5548</a></li>
<li>Add peer name and port to gRPC observation contexts <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/3512">#3512</a></li>
<li>Use direct equals call instead of Objects.equals wrapper <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5840">#5840</a></li>
<li>Remove special handling of 404/301 from JDK HTTP client
instrumentation <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5838">#5838</a></li>
<li>Make Timer and LongTaskTimer output similar in LoggingMeterRegistry
<a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5835">#5835</a></li>
<li>Remove special handling of 404 and redirection statuses from Jetty
client instrumentation <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5825">#5825</a></li>
<li>Log deprecation warning when creating SignalFxMeterRegistry <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5824">#5824</a></li>
<li>Log metrics recording failures in CountedAspect and TimedAspect <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5820">#5820</a></li>
<li>Remove special handling of 404/301 from OkHttp instrumentation <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5814">#5814</a></li>
<li>Support AutoShutdownDelegatedExecutorService in
ExecutorServiceMetrics <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5811">#5811</a></li>
<li>Deprecate micrometer-registry-signalfx in favor of
micrometer-registry-otlp <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5807">#5807</a></li>
<li>Rebind <code>Log4j2Metrics</code> when
<code>LoggerContext#reconfigure</code> is called <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5756">#5756</a></li>
<li>Send metrics via any protocol in the OTLP Registry <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5690">#5690</a></li>
<li>Improve average performance of DefaultLongTaskTimer for out-of-order
stopping <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5591">#5591</a></li>
<li>Improve OtlpMetricsSender API <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5994">#5994</a></li>
<li>Support configuring exponential histograms at the meter level <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5459">#5459</a></li>
<li>Allow TimedAspect/CountedAspect to create tags based on method
result <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/3058">#3058</a></li>
</ul>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>Do not leak OTLP types on public-facing API <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5699">#5699</a></li>
<li>micrometer-observation-test brings unnecessary JUnit dependencies,
leading to conflicts <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6012">#6012</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Bump io.opentelemetry.proto:opentelemetry-proto from 1.4.0-alpha to
1.5.0-alpha <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5798">#5798</a></li>
<li>Bump com.google.cloud:libraries-bom from 26.55.0 to 26.56.0 <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5991">#5991</a></li>
<li>Bump com.google.cloud:google-cloud-monitoring from 3.59.0 to 3.60.0
<a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5986">#5986</a></li>
<li>Bump com.google.auth:google-auth-library-oauth2-http from 1.32.1 to
1.33.0 <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5963">#5963</a></li>
<li>Bump software.amazon.awssdk:cloudwatch from 2.29.46 to 2.30.11 <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/5863">#5863</a></li>
</ul>
<h2>❤️ Contributors</h2>
<p>Thank you to all the contributors who worked on this release:</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e13042badc"><code>e13042b</code></a>
Bump software.amazon.awssdk:cloudwatch from 2.31.40 to 2.31.41 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6228">#6228</a>)</li>
<li><a
href="571793b84e"><code>571793b</code></a>
Merge branch '1.14.x'</li>
<li><a
href="315c1b1817"><code>315c1b1</code></a>
Merge branch '1.13.x' into 1.14.x</li>
<li><a
href="a3ae027d8c"><code>a3ae027</code></a>
Bump com.tngtech.archunit:archunit-junit5 from 1.3.1 to 1.3.2 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6225">#6225</a>)</li>
<li><a
href="ac6c26f7ba"><code>ac6c26f</code></a>
Merge branch '1.14.x'</li>
<li><a
href="163203f981"><code>163203f</code></a>
Add missing colons in &quot;Environment&quot; section in bug_report.md
(<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6223">#6223</a>)</li>
<li><a
href="1713feed26"><code>1713fee</code></a>
Bump maven-resolver from 1.9.22 to 1.9.23 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6222">#6222</a>)</li>
<li><a
href="e31548477a"><code>e315484</code></a>
Bump software.amazon.awssdk:cloudwatch from 2.31.39 to 2.31.40 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6221">#6221</a>)</li>
<li><a
href="d6b8d4e847"><code>d6b8d4e</code></a>
Bump com.google.cloud:libraries-bom from 26.59.0 to 26.60.0 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6220">#6220</a>)</li>
<li><a
href="121056e6d5"><code>121056e</code></a>
Bump software.amazon.awssdk:cloudwatch from 2.31.38 to 2.31.39 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6217">#6217</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/micrometer-metrics/micrometer/compare/v1.14.7...v1.15.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.micrometer:micrometer-core&package-manager=gradle&previous-version=1.14.7&new-version=1.15.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:53:02 +01:00
dependabot[bot]
f50f7230d0
Bump org.springframework.security:spring-security-saml2-service-provider from 6.4.5 to 6.5.0 (#3549)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[org.springframework.security:spring-security-saml2-service-provider](https://github.com/spring-projects/spring-security)
from 6.4.5 to 6.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spring-projects/spring-security/releases">org.springframework.security:spring-security-saml2-service-provider's
releases</a>.</em></p>
<blockquote>
<h2>6.5.0</h2>
<h2> New Features</h2>
<ul>
<li>Add documentation for DPoP support <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17072">#17072</a></li>
<li>Add logging to CsrfTokenRequestHandler implementations <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16994">#16994</a></li>
<li>Add mapping for DPoP in DefaultMapOAuth2AccessTokenResponseConverter
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/16806">#16806</a></li>
<li>Bump Gradle Wrapper from 8.13 to 8.14 <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17018">#17018</a></li>
<li>ClientRegistrations.fromIssuerLocation does not include failure
information <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17015">#17015</a></li>
<li>Fix Typo In SubjectDnX509PrincipalExtractorTests <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16997">#16997</a></li>
<li>Implement internal cache in JtiClaimValidator <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17107">#17107</a></li>
<li>Polish javadoc <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16924">#16924</a></li>
<li>Remove unused classes <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16935">#16935</a></li>
<li>Replace NimbusOpaqueTokenIntrospector with
SpringOpaqueTokenIntrospector in Documentation <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16962">#16962</a></li>
<li>RequestHeaderAuthenticationFilter creates a session even if not
configured to do so <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17147">#17147</a></li>
</ul>
<h2>🪲 Bug Fixes</h2>
<ul>
<li>Add FunctionalInterface To X509PrincipalExtractor <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16952">#16952</a></li>
<li>Change NonNull import from reactor to spring <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16571">#16571</a></li>
<li>Fix DPoP jkt claim to be JWK SHA-256 thumbprint <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17080">#17080</a></li>
<li>Minor error in the Handling Logouts documentation <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17049">#17049</a></li>
<li>SecurityAnnotationScanner's method comparison should use .equals <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17145">#17145</a></li>
<li>Use proper configuration key in Opaque Token documentation <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17014">#17014</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Bump com.fasterxml.jackson:jackson-bom from 2.18.3 to 2.18.4 <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17069">#17069</a></li>
<li>Bump com.fasterxml.jackson:jackson-bom from 2.18.3 to 2.19.0 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16995">#16995</a></li>
<li>Bump com.google.code.gson:gson from 2.13.0 to 2.13.1 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16990">#16990</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.0.RELEASE to
0.29.1.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17024">#17024</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.1.RELEASE to
0.29.2.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17095">#17095</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.6 to 1.14.7 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17096">#17096</a></li>
<li>Bump io.mockk:mockk from 1.14.0 to 1.14.2 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17019">#17019</a></li>
<li>Bump io.projectreactor:reactor-bom from 2023.0.17 to 2023.0.18 <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17111">#17111</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.5 to
1.0.6 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17040">#17040</a></li>
<li>Bump org-apache-maven-resolver from 1.9.22 to 1.9.23 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17088">#17088</a></li>
<li>Bump org-eclipse-jetty from 11.0.24 to 11.0.25 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16761">#16761</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.13.Final to
6.6.14.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17089">#17089</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.14.Final to
6.6.15.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17105">#17105</a></li>
<li>Bump org.seleniumhq.selenium:selenium-java from 4.31.0 to 4.32.0 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17037">#17037</a></li>
<li>Bump org.springframework.data:spring-data-bom from 2024.1.4 to
2024.1.5 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/16981">#16981</a></li>
<li>Bump org.springframework.data:spring-data-bom from 2024.1.5 to
2024.1.6 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17137">#17137</a></li>
<li>Bump org.springframework:spring-framework-bom from 6.2.6 to 6.2.7 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17124">#17124</a></li>
</ul>
<h2>🔩 Build Updates</h2>
<ul>
<li>Release 6.5.0 <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17138">#17138</a></li>
</ul>
<h2>❤️ Contributors</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0fd0e9335a"><code>0fd0e93</code></a>
Release 6.5.0</li>
<li><a
href="78dd02a4c1"><code>78dd02a</code></a>
Merge branch '6.4.x' into 6.5.x</li>
<li><a
href="edc8735eb8"><code>edc8735</code></a>
Merge branch '6.3.x' into 6.4.x</li>
<li><a
href="cae3467a8d"><code>cae3467</code></a>
Improve AbstractPreAuthenticatedProcessingFilter docs</li>
<li><a
href="9a8f9a91bc"><code>9a8f9a9</code></a>
Merge branch '6.4.x' into 6.5.x</li>
<li><a
href="c972de5369"><code>c972de5</code></a>
Use .equals to Compare Methods</li>
<li><a
href="bf2aaa1b18"><code>bf2aaa1</code></a>
Use .equals to Compare Methods</li>
<li><a
href="6fb0591109"><code>6fb0591</code></a>
Merge branch
'gradle/6.5.x/org.springframework.data-spring-data-bom-2024.1.6'...</li>
<li><a
href="390972c4a0"><code>390972c</code></a>
Merge branch '6.4.x' into 6.5.x</li>
<li><a
href="3690517395"><code>3690517</code></a>
Merge branch
'gradle/6.4.x/org.springframework.data-spring-data-bom-2024.1.6'...</li>
<li>Additional commits viewable in <a
href="https://github.com/spring-projects/spring-security/compare/6.4.5...6.5.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework.security:spring-security-saml2-service-provider&package-manager=gradle&previous-version=6.4.5&new-version=6.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:52:50 +01:00
dependabot[bot]
8ecd4e9c36
Bump org.springframework:spring-webmvc from 6.2.6 to 6.2.7 (#3547)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[org.springframework:spring-webmvc](https://github.com/spring-projects/spring-framework)
from 6.2.6 to 6.2.7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spring-projects/spring-framework/releases">org.springframework:spring-webmvc's
releases</a>.</em></p>
<blockquote>
<h2>v6.2.7</h2>
<h2> New Features</h2>
<ul>
<li>Forward more methods to underlying InputStream in
NonClosingInputStream <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34893">#34893</a></li>
<li>Introduce Spring property for the default property placeholder
escape character <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34865">#34865</a></li>
<li>Close ApplicationContext once AOT processing has completed <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34841">#34841</a></li>
<li>Fix
<code>AbstractJackson2HttpMessageConverter#getObjectMappersForType</code>
nullness <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34811">#34811</a></li>
<li>Add option for case-insensitive match to PatternMatchUtils <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34801">#34801</a></li>
<li>RestClient <code>@RequestBody</code> parameters lose generic type
information when creating HTTP service beans <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34793">#34793</a></li>
<li>Adds option to set Principal in MockServerWebExchange <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34789">#34789</a></li>
</ul>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>Beans created by FactoryBean are not considered as autowiring
candidates if another thread holds a singletonLock <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34902">#34902</a></li>
<li><code>PropertySourcesPlaceholderConfigurer</code> placeholder
resolution fails in several scenarios <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34861">#34861</a></li>
<li>HttpComponentsClientHttpRequestFactory setConnectionRequestTimeout
not working with httpclient 5.3.1 <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34851">#34851</a></li>
<li>Fragment.create() requires mutable map - which is unusable when used
with Kotlin <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34848">#34848</a></li>
<li>Duplicate <code>BeanOverrideHandler</code> discovered in
<code>@Nested</code> test case with superclass from different class or
in interface implemented multiple times <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34844">#34844</a></li>
<li>Accidental ClassLoader defineClass enforcement after <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34677">#34677</a>
<a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34824">#34824</a></li>
<li>HttpEntity.EMPTY headers should not be possible to mutate via
HttpHeaders constructor <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34812">#34812</a></li>
<li>AbstractFileResolvingResource.exists incorrectly reports result for
resources inside of spring-boot executable jar <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34796">#34796</a></li>
<li>Correctly expand query param with same name from URI variables array
<a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34783">#34783</a></li>
<li>R2DBC <code>NamedParameterUtils</code> only expands reused
collection parameter once <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34768">#34768</a></li>
<li><code>PathMatchingResourcePatternResolver</code> wrongly assumes
that <code>target/classes</code> always exists <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34764">#34764</a></li>
</ul>
<h2>📔 Documentation</h2>
<ul>
<li>Clarify <code>CompositePropertySource</code> behavior for
<code>EnumerablePropertySource</code> contract <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34886">#34886</a></li>
<li>Javadoc and <code>@Nullable</code> annotation for
<code>servletContext</code> parameter of
<code>ConfigurableWebEnvironment.initPropertySources</code> are
contradictory <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34845">#34845</a></li>
<li>Spring MVC: <code>@EnableAsync</code> needs to be redeclared for
each ApplicationContext <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34843">#34843</a></li>
<li>Provide a working example instead of unclear placeholders <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34828">#34828</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Upgrade to Micrometer 1.14.7 <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34889">#34889</a></li>
<li>Upgrade to Reactor 2024.0.6 <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34898">#34898</a></li>
</ul>
<h2>❤️ Contributors</h2>
<p>Thank you to all the contributors who worked on this release:</p>
<p><a href="https://github.com/Artur"><code>@​Artur</code></a>-, <a
href="https://github.com/blake-bauman"><code>@​blake-bauman</code></a>,
<a href="https://github.com/iifawzi"><code>@​iifawzi</code></a>, <a
href="https://github.com/kilink"><code>@​kilink</code></a>, <a
href="https://github.com/quaff"><code>@​quaff</code></a>, <a
href="https://github.com/whlit"><code>@​whlit</code></a>, and <a
href="https://github.com/zzoe2346"><code>@​zzoe2346</code></a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ba590ac9e4"><code>ba590ac</code></a>
Release v6.2.7</li>
<li><a
href="ee62701f56"><code>ee62701</code></a>
Make use of PatternMatchUtils ignoreCase option</li>
<li><a
href="fa168ca78a"><code>fa168ca</code></a>
Revise FactoryBean locking behavior for strict/lenient consistency</li>
<li><a
href="3c228a5c1d"><code>3c228a5</code></a>
Add missing <a href="https://github.com/since"><code>@​since</code></a>
tags in PatternMatchUtils</li>
<li><a
href="9bf6b8cddf"><code>9bf6b8c</code></a>
Upgrade to Reactor 2024.0.6</li>
<li><a
href="37ecdd1437"><code>37ecdd1</code></a>
Forward more methods to underlying InputStream in
NonClosingInputStream</li>
<li><a
href="73f1c5a189"><code>73f1c5a</code></a>
Polishing</li>
<li><a
href="4d296fb4ca"><code>4d296fb</code></a>
Upgrade to Micrometer 1.14.7</li>
<li><a
href="6a9444473f"><code>6a94444</code></a>
Clarify CompositePropertySource behavior for EnumerablePropertySource
contract</li>
<li><a
href="03ae97b2eb"><code>03ae97b</code></a>
Introduce Spring property for default escape character for
placeholders</li>
<li>Additional commits viewable in <a
href="https://github.com/spring-projects/spring-framework/compare/v6.2.6...v6.2.7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework:spring-webmvc&package-manager=gradle&previous-version=6.2.6&new-version=6.2.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:52:38 +01:00
dependabot[bot]
9aa692674f
Bump org.sonarqube from 6.1.0.5360 to 6.2.0.5505 (#3546)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps org.sonarqube from 6.1.0.5360 to 6.2.0.5505.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.sonarqube&package-manager=gradle&previous-version=6.1.0.5360&new-version=6.2.0.5505)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:52:15 +01:00
dependabot[bot]
89992fe643
Bump org.springframework:spring-jdbc from 6.2.6 to 6.2.7 (#3545)
Bumps
[org.springframework:spring-jdbc](https://github.com/spring-projects/spring-framework)
from 6.2.6 to 6.2.7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spring-projects/spring-framework/releases">org.springframework:spring-jdbc's
releases</a>.</em></p>
<blockquote>
<h2>v6.2.7</h2>
<h2> New Features</h2>
<ul>
<li>Forward more methods to underlying InputStream in
NonClosingInputStream <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34893">#34893</a></li>
<li>Introduce Spring property for the default property placeholder
escape character <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34865">#34865</a></li>
<li>Close ApplicationContext once AOT processing has completed <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34841">#34841</a></li>
<li>Fix
<code>AbstractJackson2HttpMessageConverter#getObjectMappersForType</code>
nullness <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34811">#34811</a></li>
<li>Add option for case-insensitive match to PatternMatchUtils <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34801">#34801</a></li>
<li>RestClient <code>@RequestBody</code> parameters lose generic type
information when creating HTTP service beans <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34793">#34793</a></li>
<li>Adds option to set Principal in MockServerWebExchange <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34789">#34789</a></li>
</ul>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>Beans created by FactoryBean are not considered as autowiring
candidates if another thread holds a singletonLock <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34902">#34902</a></li>
<li><code>PropertySourcesPlaceholderConfigurer</code> placeholder
resolution fails in several scenarios <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34861">#34861</a></li>
<li>HttpComponentsClientHttpRequestFactory setConnectionRequestTimeout
not working with httpclient 5.3.1 <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34851">#34851</a></li>
<li>Fragment.create() requires mutable map - which is unusable when used
with Kotlin <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34848">#34848</a></li>
<li>Duplicate <code>BeanOverrideHandler</code> discovered in
<code>@Nested</code> test case with superclass from different class or
in interface implemented multiple times <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34844">#34844</a></li>
<li>Accidental ClassLoader defineClass enforcement after <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34677">#34677</a>
<a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34824">#34824</a></li>
<li>HttpEntity.EMPTY headers should not be possible to mutate via
HttpHeaders constructor <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34812">#34812</a></li>
<li>AbstractFileResolvingResource.exists incorrectly reports result for
resources inside of spring-boot executable jar <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34796">#34796</a></li>
<li>Correctly expand query param with same name from URI variables array
<a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34783">#34783</a></li>
<li>R2DBC <code>NamedParameterUtils</code> only expands reused
collection parameter once <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34768">#34768</a></li>
<li><code>PathMatchingResourcePatternResolver</code> wrongly assumes
that <code>target/classes</code> always exists <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34764">#34764</a></li>
</ul>
<h2>📔 Documentation</h2>
<ul>
<li>Clarify <code>CompositePropertySource</code> behavior for
<code>EnumerablePropertySource</code> contract <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34886">#34886</a></li>
<li>Javadoc and <code>@Nullable</code> annotation for
<code>servletContext</code> parameter of
<code>ConfigurableWebEnvironment.initPropertySources</code> are
contradictory <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34845">#34845</a></li>
<li>Spring MVC: <code>@EnableAsync</code> needs to be redeclared for
each ApplicationContext <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34843">#34843</a></li>
<li>Provide a working example instead of unclear placeholders <a
href="https://redirect.github.com/spring-projects/spring-framework/pull/34828">#34828</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Upgrade to Micrometer 1.14.7 <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34889">#34889</a></li>
<li>Upgrade to Reactor 2024.0.6 <a
href="https://redirect.github.com/spring-projects/spring-framework/issues/34898">#34898</a></li>
</ul>
<h2>❤️ Contributors</h2>
<p>Thank you to all the contributors who worked on this release:</p>
<p><a href="https://github.com/Artur"><code>@​Artur</code></a>-, <a
href="https://github.com/blake-bauman"><code>@​blake-bauman</code></a>,
<a href="https://github.com/iifawzi"><code>@​iifawzi</code></a>, <a
href="https://github.com/kilink"><code>@​kilink</code></a>, <a
href="https://github.com/quaff"><code>@​quaff</code></a>, <a
href="https://github.com/whlit"><code>@​whlit</code></a>, and <a
href="https://github.com/zzoe2346"><code>@​zzoe2346</code></a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ba590ac9e4"><code>ba590ac</code></a>
Release v6.2.7</li>
<li><a
href="ee62701f56"><code>ee62701</code></a>
Make use of PatternMatchUtils ignoreCase option</li>
<li><a
href="fa168ca78a"><code>fa168ca</code></a>
Revise FactoryBean locking behavior for strict/lenient consistency</li>
<li><a
href="3c228a5c1d"><code>3c228a5</code></a>
Add missing <a href="https://github.com/since"><code>@​since</code></a>
tags in PatternMatchUtils</li>
<li><a
href="9bf6b8cddf"><code>9bf6b8c</code></a>
Upgrade to Reactor 2024.0.6</li>
<li><a
href="37ecdd1437"><code>37ecdd1</code></a>
Forward more methods to underlying InputStream in
NonClosingInputStream</li>
<li><a
href="73f1c5a189"><code>73f1c5a</code></a>
Polishing</li>
<li><a
href="4d296fb4ca"><code>4d296fb</code></a>
Upgrade to Micrometer 1.14.7</li>
<li><a
href="6a9444473f"><code>6a94444</code></a>
Clarify CompositePropertySource behavior for EnumerablePropertySource
contract</li>
<li><a
href="03ae97b2eb"><code>03ae97b</code></a>
Introduce Spring property for default escape character for
placeholders</li>
<li>Additional commits viewable in <a
href="https://github.com/spring-projects/spring-framework/compare/v6.2.6...v6.2.7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework:spring-jdbc&package-manager=gradle&previous-version=6.2.6&new-version=6.2.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:52:04 +01:00
dependabot[bot]
1f56ccfc99
Bump gradle/actions from 4.3.1 to 4.4.0 (#3544)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps [gradle/actions](https://github.com/gradle/actions) from 4.3.1 to
4.4.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/gradle/actions/releases">gradle/actions's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.0</h2>
<p>This release updates 2 downstream components:</p>
<ul>
<li>Develocity injection has been updated to <a
href="https://github.com/gradle/develocity-ci-injection/releases/tag/v2.0">v2.0</a>
<ul>
<li>Some environment variables related to Develocity injection have been
renamed. All vars now being with <code>DEVELOCITY_INJECTION_</code>.
Check <a
href="https://github.com/gradle/actions/blob/main/docs/setup-gradle.md#configuring-develocity-injection">the
docs</a> for more details.</li>
</ul>
</li>
<li>Dependency-graph plugin has been updated to <a
href="https://github.com/gradle/github-dependency-graph-gradle-plugin/releases/tag/v1.4.0">v1.4.0</a>
<ul>
<li>The 'detector' values included in the generated graph can now be
configured via environment variables.</li>
</ul>
</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Update develocity-injection init script to v1.3 by <a
href="https://github.com/bot-githubaction"><code>@​bot-githubaction</code></a>
in <a
href="https://redirect.github.com/gradle/actions/pull/592">gradle/actions#592</a></li>
<li>Update develocity-injection init script to v2.0 by <a
href="https://github.com/bot-githubaction"><code>@​bot-githubaction</code></a>
in <a
href="https://redirect.github.com/gradle/actions/pull/593">gradle/actions#593</a></li>
<li>[StepSecurity] ci: Harden GitHub Actions by <a
href="https://github.com/step-security-bot"><code>@​step-security-bot</code></a>
in <a
href="https://redirect.github.com/gradle/actions/pull/597">gradle/actions#597</a></li>
<li>Use v1.4.0 of dependency graph plugin by <a
href="https://github.com/bigdaz"><code>@​bigdaz</code></a> in <a
href="https://redirect.github.com/gradle/actions/pull/638">gradle/actions#638</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/step-security-bot"><code>@​step-security-bot</code></a>
made their first contribution in <a
href="https://redirect.github.com/gradle/actions/pull/597">gradle/actions#597</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/gradle/actions/compare/v4.3.1...v4.4.0">https://github.com/gradle/actions/compare/v4.3.1...v4.4.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8379f6a132"><code>8379f6a</code></a>
Use v1.4.0 of dependency graph plugin (<a
href="https://redirect.github.com/gradle/actions/issues/638">#638</a>)</li>
<li><a
href="9f79b5fa2c"><code>9f79b5f</code></a>
[bot] Update dist directory</li>
<li><a
href="e093fac84c"><code>e093fac</code></a>
Bump the npm-dependencies group in /sources with 5 updates (<a
href="https://redirect.github.com/gradle/actions/issues/636">#636</a>)</li>
<li><a
href="768a17f348"><code>768a17f</code></a>
Bump the npm-dependencies group in /sources with 2 updates (<a
href="https://redirect.github.com/gradle/actions/issues/635">#635</a>)</li>
<li><a
href="3654113772"><code>3654113</code></a>
[bot] Update dist directory</li>
<li><a
href="2ad385cb2a"><code>2ad385c</code></a>
Replace use of typed-rest-client with <code>@​actions/http-client</code>
(<a
href="https://redirect.github.com/gradle/actions/issues/634">#634</a>)</li>
<li><a
href="95dcf96b0d"><code>95dcf96</code></a>
[bot] Update dist directory</li>
<li><a
href="2e3238a664"><code>2e3238a</code></a>
Bump actions/download-artifact from 4.2.1 to 4.3.0 in
/.github/actions/init-i...</li>
<li><a
href="39dddb8ae7"><code>39dddb8</code></a>
Remove direct use of octokit/request-error (<a
href="https://redirect.github.com/gradle/actions/issues/632">#632</a>)</li>
<li><a
href="755ed7db09"><code>755ed7d</code></a>
[bot] Update dist directory</li>
<li>Additional commits viewable in <a
href="06832c7b30...8379f6a132">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=gradle/actions&package-manager=github_actions&previous-version=4.3.1&new-version=4.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:51:52 +01:00
dependabot[bot]
f290f62e23
Bump actions/dependency-review-action from 4.7.0 to 4.7.1 (#3543)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[actions/dependency-review-action](https://github.com/actions/dependency-review-action)
from 4.7.0 to 4.7.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/dependency-review-action/releases">actions/dependency-review-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.7.1</h2>
<ul>
<li>Packages added to <code>allow-dependencies-licenses</code> will be
allowed even if the package in question has no license information <a
href="https://redirect.github.com/actions/dependency-review-action/issues/889">#889</a></li>
<li>License expressions (e.g. <code>Ruby OR GPL-2.0</code>) in the allow
list are automatically discarded so that they don't invalidate the whole
allow list, which should just be license identifier (e.g.
<code>Ruby</code>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="da24556b54"><code>da24556</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/933">#933</a>
from actions/dangoor/471-release</li>
<li><a
href="9af0caf0e5"><code>9af0caf</code></a>
Bump version number for 4.7.1</li>
<li><a
href="d8f2df20d5"><code>d8f2df2</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/932">#932</a>
from actions/907-disallow-expression</li>
<li><a
href="6e9307a3d4"><code>6e9307a</code></a>
Discard allow list entries that are not SPDX IDs</li>
<li><a
href="8805179dc9"><code>8805179</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/930">#930</a>
from actions/889-allow-no-license</li>
<li><a
href="014300b08c"><code>014300b</code></a>
Update build</li>
<li><a
href="34486f306e"><code>34486f3</code></a>
Check namespaces when excluding license checks</li>
<li><a
href="9b155d6432"><code>9b155d6</code></a>
Update build</li>
<li><a
href="f199659a6a"><code>f199659</code></a>
Allowing dependencies works with no licenses</li>
<li>See full diff in <a
href="38ecb5b593...da24556b54">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/dependency-review-action&package-manager=github_actions&previous-version=4.7.0&new-version=4.7.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:51:32 +01:00
dependabot[bot]
74fcf01d03
Bump github/codeql-action from 3.28.17 to 3.28.18 (#3542)
Bumps [github/codeql-action](https://github.com/github/codeql-action)
from 3.28.17 to 3.28.18.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.28.18</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.18 - 16 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2893">#2893</a></li>
<li>Skip validating SARIF produced by CodeQL for improved performance.
<a
href="https://redirect.github.com/github/codeql-action/pull/2894">#2894</a></li>
<li>The number of threads and amount of RAM used by CodeQL can now be
set via the <code>CODEQL_THREADS</code> and <code>CODEQL_RAM</code>
runner environment variables. If set, these environment variables
override the <code>threads</code> and <code>ram</code> inputs
respectively. <a
href="https://redirect.github.com/github/codeql-action/pull/2891">#2891</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.18/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.28.18 - 16 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2893">#2893</a></li>
<li>Skip validating SARIF produced by CodeQL for improved performance.
<a
href="https://redirect.github.com/github/codeql-action/pull/2894">#2894</a></li>
<li>The number of threads and amount of RAM used by CodeQL can now be
set via the <code>CODEQL_THREADS</code> and <code>CODEQL_RAM</code>
runner environment variables. If set, these environment variables
override the <code>threads</code> and <code>ram</code> inputs
respectively. <a
href="https://redirect.github.com/github/codeql-action/pull/2891">#2891</a></li>
</ul>
<h2>3.28.17 - 02 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2872">#2872</a></li>
</ul>
<h2>3.28.16 - 23 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.1. <a
href="https://redirect.github.com/github/codeql-action/pull/2863">#2863</a></li>
</ul>
<h2>3.28.15 - 07 Apr 2025</h2>
<ul>
<li>Fix bug where the action would fail if it tried to produce a debug
artifact with more than 65535 files. <a
href="https://redirect.github.com/github/codeql-action/pull/2842">#2842</a></li>
</ul>
<h2>3.28.14 - 07 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.0. <a
href="https://redirect.github.com/github/codeql-action/pull/2838">#2838</a></li>
</ul>
<h2>3.28.13 - 24 Mar 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.12 - 19 Mar 2025</h2>
<ul>
<li>Dependency caching should now cache more dependencies for Java
<code>build-mode: none</code> extractions. This should speed up
workflows and avoid inconsistent alerts in some cases.</li>
<li>Update default CodeQL bundle version to 2.20.7. <a
href="https://redirect.github.com/github/codeql-action/pull/2810">#2810</a></li>
</ul>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<h2>3.28.10 - 21 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.5. <a
href="https://redirect.github.com/github/codeql-action/pull/2772">#2772</a></li>
<li>Address an issue where the CodeQL Bundle would occasionally fail to
decompress on macOS. <a
href="https://redirect.github.com/github/codeql-action/pull/2768">#2768</a></li>
</ul>
<h2>3.28.9 - 07 Feb 2025</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ff0a06e83c"><code>ff0a06e</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2896">#2896</a>
from github/update-v3.28.18-b86edfc27</li>
<li><a
href="a41e0844be"><code>a41e084</code></a>
Update changelog for v3.28.18</li>
<li><a
href="b86edfc27a"><code>b86edfc</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2893">#2893</a>
from github/update-bundle/codeql-bundle-v2.21.3</li>
<li><a
href="e93b90025f"><code>e93b900</code></a>
Merge branch 'main' into update-bundle/codeql-bundle-v2.21.3</li>
<li><a
href="510dfa3460"><code>510dfa3</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2894">#2894</a>
from github/henrymercer/skip-validating-codeql-sarif</li>
<li><a
href="492d783245"><code>492d783</code></a>
Merge branch 'main' into henrymercer/skip-validating-codeql-sarif</li>
<li><a
href="83bdf3b7f9"><code>83bdf3b</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2859">#2859</a>
from github/update-supported-enterprise-server-versions</li>
<li><a
href="cffc916774"><code>cffc916</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2891">#2891</a>
from austinpray-mixpanel/patch-1</li>
<li><a
href="4420887272"><code>4420887</code></a>
Add deprecation warning for CodeQL 2.16.5 and earlier</li>
<li><a
href="4e178c5841"><code>4e178c5</code></a>
Update supported versions table in README</li>
<li>Additional commits viewable in <a
href="60168efe1c...ff0a06e83c">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.28.17&new-version=3.28.18)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:51:13 +01:00
dependabot[bot]
1346abf0e5
Bump docker/build-push-action from 6.16.0 to 6.17.0 (#3541)
Bumps
[docker/build-push-action](https://github.com/docker/build-push-action)
from 6.16.0 to 6.17.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/build-push-action/releases">docker/build-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v6.17.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.59.0 to 0.61.0 by
<a href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1364">docker/build-push-action#1364</a></li>
</ul>
<blockquote>
<p>[!NOTE]
Build record is now exported using the <a
href="https://docs.docker.com/reference/cli/docker/buildx/history/export/"><code>buildx
history export</code></a> command instead of the legacy export-build
tool.</p>
</blockquote>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v6.16.0...v6.17.0">https://github.com/docker/build-push-action/compare/v6.16.0...v6.17.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1dc7386353"><code>1dc7386</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1364">#1364</a>
from crazy-max/history-export-cmd</li>
<li><a
href="9c9803f364"><code>9c9803f</code></a>
chore: update generated content</li>
<li><a
href="db1f6c46e8"><code>db1f6c4</code></a>
DOCKER_BUILD_EXPORT_LEGACY env var to opt-in for legacy export</li>
<li><a
href="721e8c79de"><code>721e8c7</code></a>
Bump <code>@​docker/actions-toolkit</code> from 0.59.0 to 0.61.0</li>
<li>See full diff in <a
href="14487ce63c...1dc7386353">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=docker/build-push-action&package-manager=github_actions&previous-version=6.16.0&new-version=6.17.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:50:59 +01:00
Ludy
523240554f
Fix empty-parameter issue in updateUserSettings by using @RequestBody map (#3536)
# Description of Changes

Please provide a summary of the changes, including:


- **What was changed:**  
- Refactored the `updateUserSettings` method in `UserController` to
accept a `@RequestBody Map<String, String>` named `updates` instead of
pulling parameters from `HttpServletRequest`.
- Removed the now-unused `HashMap` import and the manual
parameter-extraction loop.

- **Why the change was made:**  
- **Bug Fix:** The previous implementation relied on
`request.getParameterMap()`, which was consistently empty, so no
settings were ever applied.
- Simplifies controller logic by leveraging Spring’s request-body
binding.
- Improves readability and maintainability, removing boilerplate and
error-prone code.

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] 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)
- [x] I have performed a self-review of my own code
- [x] 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: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-20 07:58:27 +01:00
stirlingbot[bot]
e6a9e7a584
🌐 Sync Translations + Update README Progress Table (#3531)
### Description of Changes

This Pull Request was automatically generated to synchronize updates to
translation files and documentation. Below are the details of the
changes made:

#### **1. Synchronization of Translation Files**
- Updated translation files (`messages_*.properties`) to reflect changes
in the reference file `messages_en_GB.properties`.
- Ensured consistency and synchronization across all supported language
files.
- Highlighted any missing or incomplete translations.

#### **2. Update README.md**
- Generated the translation progress table in `README.md`.
- Added a summary of the current translation status for all supported
languages.
- Included up-to-date statistics on translation coverage.

#### **Why these changes are necessary**
- Keeps translation files aligned with the latest reference updates.
- Ensures the documentation reflects the current translation progress.

---

Auto-generated by [create-pull-request][1].

[1]: https://github.com/peter-evans/create-pull-request

Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-05-19 16:46:54 +01:00
stirlingbot[bot]
5bf2fed235
Update 3rd Party Licenses (#3523)
Auto-generated by StirlingBot

Signed-off-by: stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-05-19 14:42:18 +01:00
Anthony Stirling
21832729d2
JUnits JUnits JUnits, so many JUnits (#3537)
# 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: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
2025-05-19 14:12:06 +01:00
Anthony Stirling
f94b8c3b22
Floating keys for pro users (#3535)
# 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.
2025-05-19 10:00:58 +01:00
NeilJared
b26ecbc3b7
Update messages_es_ES.properties (#3527)
Updated es_ES translation and made minor improvements.
2025-05-16 12:23:55 +01:00
Dr.XYZ
3b2b14609d
Update zh_TW Traditional Chinese locale (#3524)
# 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

- [x] 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)
- [x] 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)
- [x] I have performed a self-review of my own code
- [x] 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.
2025-05-16 12:23:37 +01:00
Ludy
52f09f1840
Improve Type Safety and OpenAPI Schema for PDF API Controllers and Models (#3470)
# Description of Changes

- **What was changed**  
- Updated controller methods to use strongly‐typed primitives (`int`,
`long`, `boolean`) instead of `String` for numeric and boolean
parameters, eliminating calls to `Integer.parseInt`/`Long.parseLong` and
improving null‐safety (`Boolean.TRUE.equals(...)`).
- Enhanced all API request model classes with richer Swagger/OpenAPI
annotations: added `requiredMode`, `defaultValue`, `allowableValues`,
`format`, `pattern`, and tightened schema descriptions for all fields.
- Refactored HTML form templates for “Remove Blank Pages” to include
`min`, `max`, and `step` attributes on numeric inputs, matching the
updated validation rules.

- **Why the change was made**  
- **Type safety & robustness**: Shifting from `String` to native types
prevents runtime parsing errors, simplifies controller logic, and makes
default values explicit.
- **Better API documentation & validation**: Enriching the Swagger
annotations ensures generated docs accurately reflect required fields,
default values, and permitted ranges, which improves client code
generation and developer experience.
- **Consistency across codebase**: Aligning all request models and
controllers enforces a uniform coding style and reduces bugs.

#3406

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] 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)
- [x] I have performed a self-review of my own code
- [x] 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.
2025-05-16 12:23:01 +01:00
Ludy
c660ad80ce
Update legal URLs and improve OpenAPI metadata configuration (#3522)
# Description of Changes

Please provide a summary of the changes, including:

- Updated default Terms & Conditions URL from `/terms-and-conditions` to
`/terms` in:
  - `InitialSetup.java`
  - `settings.yml.template`
  - `allEndpointsRemovedSettings.yml`
- Improved OpenAPI metadata in `OpenApiConfig.java`:
  - Added contact information (`name`, `url`, `email`)
  - Added license section with MIT license
  - Included terms of service link
- Changed string comparison in `MetricsConfig.java` to use
`"constant".equals(...)` format
- Cleaned up and unified YAML formatting and comments
- Merged and restructured `enterpriseEdition` settings under
`premium.proFeatures`

### Why the change was made

- Ensure legal links are consistent and up-to-date
- Improve clarity and completeness of the OpenAPI specification for
external consumers
- Follow best practices for code readability and configuration structure
- Prevent misconfiguration from outdated or redundant YAML sections

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] 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)
- [x] I have performed a self-review of my own code
- [x] 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.
2025-05-13 23:06:14 +01:00
dependabot[bot]
70717813f6
Bump io.micrometer:micrometer-core from 1.14.6 to 1.14.7 (#3521)
Bumps
[io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer)
from 1.14.6 to 1.14.7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/micrometer-metrics/micrometer/releases">io.micrometer:micrometer-core's
releases</a>.</em></p>
<blockquote>
<h2>1.14.7</h2>
<h2> New Features</h2>
<ul>
<li>Replace Meter.Id.getTags() with cheaper alternatives <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6147">#6147</a></li>
</ul>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>MultiGauge doesn't work with MeterFilter.map() <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6146">#6146</a></li>
<li>Record cache.size in CaffeineCacheMetrics without enabling
recordStats() <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6128">#6128</a></li>
<li>TimedHandler shutdown hanging indefinitely <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6194">#6194</a></li>
<li>Use snapshot consistently in AppOpticsMeterRegistry.writeSummary()
<a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6181">#6181</a></li>
</ul>
<h2>❤️ Contributors</h2>
<p>Thank you to all the contributors who worked on this release:</p>
<p><a href="https://github.com/AlexElin"><code>@​AlexElin</code></a>, <a
href="https://github.com/RafeArnold"><code>@​RafeArnold</code></a>, and
<a href="https://github.com/izeye"><code>@​izeye</code></a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b6e5031303"><code>b6e5031</code></a>
Bump com.tngtech.archunit:archunit-junit5 from 1.3.1 to 1.3.2 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6226">#6226</a>)</li>
<li><a
href="6567cdccd3"><code>6567cdc</code></a>
Merge branch '1.13.x' into 1.14.x</li>
<li><a
href="80d4c9d986"><code>80d4c9d</code></a>
Call Shutdown#check after finishing timing (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6194">#6194</a>)</li>
<li><a
href="7f82709bb2"><code>7f82709</code></a>
Bump maven-resolver from 1.9.22 to 1.9.23 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6219">#6219</a>)</li>
<li><a
href="a1a4f3d83d"><code>a1a4f3d</code></a>
Bump maven-resolver from 1.9.22 to 1.9.23 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6218">#6218</a>)</li>
<li><a
href="a6adb3a058"><code>a6adb3a</code></a>
Merge branch '1.13.x' into 1.14.x</li>
<li><a
href="fb2d4da16e"><code>fb2d4da</code></a>
Get Google Cloud project ID from env var for integration tests</li>
<li><a
href="4f0cf532a9"><code>4f0cf53</code></a>
Bump com.fasterxml.jackson.core:jackson-databind from 2.18.3 to 2.18.4
(<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6214">#6214</a>)</li>
<li><a
href="33d1f7ebfd"><code>33d1f7e</code></a>
Merge branch '1.13.x' into 1.14.x</li>
<li><a
href="79939c3958"><code>79939c3</code></a>
Fix JavaDurationGetSecondsToToSeconds warnings for tests (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6207">#6207</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/micrometer-metrics/micrometer/compare/v1.14.6...v1.14.7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.micrometer:micrometer-core&package-manager=gradle&previous-version=1.14.6&new-version=1.14.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-13 23:05:26 +01:00
dependabot[bot]
662c2a4dfe
Bump org.apache.xmlgraphics:batik-all from 1.18 to 1.19 (#3520)
Bumps org.apache.xmlgraphics:batik-all from 1.18 to 1.19.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.xmlgraphics:batik-all&package-manager=gradle&previous-version=1.18&new-version=1.19)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-13 23:05:06 +01:00
dependabot[bot]
9fc174d12d
Bump actions/dependency-review-action from 4.6.0 to 4.7.0 (#3519)
Bumps
[actions/dependency-review-action](https://github.com/actions/dependency-review-action)
from 4.6.0 to 4.7.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/dependency-review-action/releases">actions/dependency-review-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.7.0</h2>
<ul>
<li>Handle complex license expressions (e.g. <code>MIT AND
GPL-2.0</code>) in allow lists (fixes <a
href="https://redirect.github.com/actions/dependency-review-action/issues/809">#809</a>
and probably others)</li>
<li>Replace <code>OTHER</code> in package licenses with
<code>LicenseRef-clearlydefined-OTHER</code> so that parsing passes</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="38ecb5b593"><code>38ecb5b</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/929">#929</a>
from actions/dangoor/4.7-release</li>
<li><a
href="0e9e935cc8"><code>0e9e935</code></a>
Version 4.7.0 release</li>
<li><a
href="69d2faa365"><code>69d2faa</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/926">#926</a>
from dangoor/dangoor/replace-other</li>
<li><a
href="7e14978e0e"><code>7e14978</code></a>
Merge branch 'actions:main' into dangoor/replace-other</li>
<li><a
href="8477905b0e"><code>8477905</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/927">#927</a>
from dangoor/dangoor/multilicense</li>
<li><a
href="f3ff3564fa"><code>f3ff356</code></a>
Update dist</li>
<li><a
href="c7565d44ec"><code>c7565d4</code></a>
Fix tests and respond to review feedback</li>
<li><a
href="82299c3bbe"><code>82299c3</code></a>
Replace OTHER with a LicenseRef</li>
<li><a
href="2013ccccfe"><code>2013ccc</code></a>
Update type definition for spdx-satisfies</li>
<li><a
href="3a2b68706a"><code>3a2b687</code></a>
Handle complex licenses (e.g. X AND Y)</li>
<li>Additional commits viewable in <a
href="ce3cf9537a...38ecb5b593">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/dependency-review-action&package-manager=github_actions&previous-version=4.6.0&new-version=4.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-13 23:04:45 +01:00
Ludy
091484fc1d
Standardize Quoted Path Syntax in Thymeleaf th:href for Consistent Link Resolution (#3515)
# Description of Changes

Please provide a summary of the changes, including:

- **What was changed**  
1. In `DeveloperGuide.md`, updated the example `<a>` tag to use
`th:href="@{'/new-feature'}"` instead of `th:href="@{/new-feature}"`.
2. In `adminSettings.html`, replaced the static `href="/usage"` with a
Thymeleaf attribute `th:href="@{'/usage'}"` to ensure proper URL
resolution.

- **Why the change was made**  
Consistently quoting paths in `th:href` improves readability and avoids
potential parsing inconsistencies in Thymeleaf templates when resolving
URLs at runtime.

---

## 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.
2025-05-12 10:37:07 +01:00
Shad CT
a595a950ab
updated the languages list (#3510)
# 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.
2025-05-12 10:36:33 +01:00
stirlingbot[bot]
cd775661ab
🤖 format everything with pre-commit by <stirlingbot> (#3514)
Auto-generated by [create-pull-request][1] with **stirlingbot**

[1]: https://github.com/peter-evans/create-pull-request

Signed-off-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-05-12 09:01:28 +01:00
Ludy
b8574dc856
Use Thymeleaf th:src for redact.js to ensure correct resource path resolution (#3511)
# Description of Changes

Please provide a summary of the changes, including:

```bash
generic_scripting.js:48 
 GET https://stirling.lan/pdfjs-legacy/js/pdfjs-legacy/pdf.sandbox.mjs net::ERR_ABORTED 404 (Not Found)

pdf_scripting_manager.js:195 setDocument: "Failed to fetch dynamically imported module: https://stirling.lan/pdfjs-legacy/js/pdfjs-legacy/pdf.sandbox.mjs".

```

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.
2025-05-11 19:14:27 +01:00
Noah Baculi
e78fd00a70
Fix README enterprise link (#3509)
# Description of Changes

Please provide a summary of the changes, including:

- Fixed broken link on the readme to the Pro/Enterprise docs.
- This was changed because the link was broken => degraded user
experience.
- Replaced the broken link with the closest valid page that I could
find.

I could not find an issue for this broken link but one can be created if
needed.

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [x] 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)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [x] 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)
- [x] 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)

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

### Testing (if applicable)

- [x] 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.
2025-05-11 07:53:20 +01:00
stirlingbot[bot]
780a1d2835
🌐 Sync Translations + Update README Progress Table (#3508)
### Description of Changes

This Pull Request was automatically generated to synchronize updates to
translation files and documentation. Below are the details of the
changes made:

#### **1. Synchronization of Translation Files**
- Updated translation files (`messages_*.properties`) to reflect changes
in the reference file `messages_en_GB.properties`.
- Ensured consistency and synchronization across all supported language
files.
- Highlighted any missing or incomplete translations.

#### **2. Update README.md**
- Generated the translation progress table in `README.md`.
- Added a summary of the current translation status for all supported
languages.
- Included up-to-date statistics on translation coverage.

#### **Why these changes are necessary**
- Keeps translation files aligned with the latest reference updates.
- Ensures the documentation reflects the current translation progress.

---

Auto-generated by [create-pull-request][1].

[1]: https://github.com/peter-evans/create-pull-request

Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-05-10 18:55:19 +01:00
Shad CT
d64f4fca4f
added Malayalam language (#3506)
# 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

- [x] 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)
- [x] 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)
- [x] I have performed a self-review of my own code
- [x] 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)

- [x] 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.
2025-05-10 18:08:26 +01:00
168 changed files with 7365 additions and 1634 deletions

View File

@ -180,7 +180,7 @@ jobs:
password: ${{ secrets.DOCKER_HUB_API }}
- name: Build and push PR-specific image
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
context: .
file: ./Dockerfile

View File

@ -24,4 +24,4 @@ jobs:
- name: "Checkout Repository"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: "Dependency Review"
uses: actions/dependency-review-action@ce3cf9537a52e8119d91fd484ab5b8a807627bf8 # v4.6.0
uses: actions/dependency-review-action@da24556b548a50705dd671f47852072ea4c105d9 # v4.7.1

View File

@ -38,7 +38,7 @@ jobs:
java-version: "17"
distribution: "adopt"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0
- name: check the licenses for compatibility
run: ./gradlew clean checkLicense

View File

@ -68,7 +68,7 @@ jobs:
java-version: "21"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0
with:
gradle-version: 8.14
@ -156,7 +156,7 @@ jobs:
java-version: "21"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0
with:
gradle-version: 8.14

View File

@ -30,7 +30,7 @@ jobs:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0
with:
gradle-version: 8.14
@ -90,7 +90,7 @@ jobs:
- name: Build and push main Dockerfile
id: build-push-regular
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
@ -135,7 +135,7 @@ jobs:
- name: Build and push Dockerfile-ultra-lite
id: build-push-lite
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
if: github.ref != 'refs/heads/main'
with:
context: .
@ -166,7 +166,7 @@ jobs:
- name: Build and push main Dockerfile fat
id: build-push-fat
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
if: github.ref != 'refs/heads/main'
with:
builder: ${{ steps.buildx.outputs.name }}

View File

@ -35,7 +35,7 @@ jobs:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0
with:
gradle-version: 8.14

View File

@ -74,6 +74,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
sarif_file: results.sarif

View File

@ -27,7 +27,7 @@ jobs:
fetch-depth: 0
- name: Setup Gradle
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0
- name: Build and analyze with Gradle
env:

View File

@ -26,7 +26,7 @@ jobs:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0
- name: Generate Swagger documentation
run: ./gradlew generateOpenApiDocs

View File

@ -46,7 +46,7 @@ jobs:
password: ${{ secrets.DOCKER_HUB_API }}
- name: Build and push test image
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
context: .
file: ./Dockerfile

24
AGENTS.md Normal file
View File

@ -0,0 +1,24 @@
# Codex Contribution Guidelines for Stirling-PDF
This file provides high-level instructions for Codex when modifying any files within this repository. Follow these rules to ensure changes remain consistent with the existing project structure.
## 1. Code Style and Formatting
- Respect the `.editorconfig` settings located in the repository root. Java files use 4 spaces; HTML, JS, and Python generally use 2 spaces. Lines should end with `LF`.
- Format Java code with `./gradlew spotlessApply` before committing.
- Review `DeveloperGuide.md` for project structure and design details before making significant changes.
## 2. Testing
- Run `./gradlew build` before committing changes to ensure the project compiles.
- If the build cannot complete due to environment restrictions, DO NOT COMMIT THE CHANGE
## 3. Commits
- Keep commits focused. Group related changes together and provide concise commit messages.
- Ensure the working tree is clean (`git status`) before concluding your work.
## 4. Pull Requests
- Summarize what was changed and why. Include build results from `./gradlew build` in the PR description.
- Note that the code was generated with the assistance of AI.
## 5. Translations
- Only modify `messages_en_GB.properties` when adding or updating translations.

View File

@ -541,7 +541,7 @@ This would generate n entries of tr for each person in exampleData
```html
<li class="nav-item">
<a class="nav-link" th:href="@{/new-feature}">New Feature</a>
<a class="nav-link" th:href="@{'/new-feature'}">New Feature</a>
</li>
```

View File

@ -112,7 +112,7 @@ Visit our comprehensive documentation at [docs.stirlingpdf.com](https://docs.sti
## Supported Languages
Stirling-PDF currently supports 39 languages!
Stirling-PDF currently supports 40 languages!
| Language | Progress |
| -------------------------------------------- | -------------------------------------- |
@ -148,7 +148,7 @@ Stirling-PDF currently supports 39 languages!
| Simplified Chinese (简体中文) (zh_CN) | ![93%](https://geps.dev/progress/93) |
| Slovakian (Slovensky) (sk_SK) | ![69%](https://geps.dev/progress/69) |
| Slovenian (Slovenščina) (sl_SI) | ![94%](https://geps.dev/progress/94) |
| Spanish (Español) (es_ES) | ![98%](https://geps.dev/progress/98) |
| Spanish (Español) (es_ES) | ![99%](https://geps.dev/progress/99) |
| Swedish (Svenska) (sv_SE) | ![87%](https://geps.dev/progress/87) |
| Thai (ไทย) (th_TH) | ![80%](https://geps.dev/progress/80) |
| Tibetan (བོད་ཡིག་) (zh_BO) | ![88%](https://geps.dev/progress/88) |
@ -156,12 +156,12 @@ Stirling-PDF currently supports 39 languages!
| Turkish (Türkçe) (tr_TR) | ![97%](https://geps.dev/progress/97) |
| Ukrainian (Українська) (uk_UA) | ![96%](https://geps.dev/progress/96) |
| Vietnamese (Tiếng Việt) (vi_VN) | ![73%](https://geps.dev/progress/73) |
| Malayalam (മലയാളം) (ml_ML) | ![99%](https://geps.dev/progress/99) |
## Stirling PDF Enterprise
Stirling PDF offers an Enterprise edition of its software. This is the same great software but with added features, support and comforts.
Check out our [Enterprise docs](https://docs.stirlingpdf.com/Enterprise%20Edition)
Check out our [Enterprise docs](https://docs.stirlingpdf.com/Pro)
## 🤝 Looking to contribute?

View File

@ -1,5 +1,6 @@
plugins {
id "java"
id 'jacoco'
id "org.springframework.boot" version "3.4.5"
id "io.spring.dependency-management" version "1.1.7"
id "org.springdoc.openapi-gradle-plugin" version "1.9.0"
@ -9,7 +10,7 @@ plugins {
id "com.github.jk1.dependency-license-report" version "2.9"
//id "nebula.lint" version "19.0.3"
id("org.panteleyev.jpackageplugin") version "1.6.1"
id "org.sonarqube" version "6.1.0.5360"
id "org.sonarqube" version "6.2.0.5505"
}
import com.github.jk1.license.render.*
@ -23,13 +24,13 @@ ext {
imageioVersion = "3.12.0"
lombokVersion = "1.18.38"
bouncycastleVersion = "1.80"
springSecuritySamlVersion = "6.4.5"
springSecuritySamlVersion = "6.5.0"
openSamlVersion = "4.3.2"
tempJrePath = null
}
group = "stirling.software"
version = "0.46.1"
version = "0.46.2"
java {
// 17 is lowest but we support and recommend 21
@ -433,7 +434,7 @@ dependencies {
}
//security updates
implementation "org.springframework:spring-webmvc:6.2.6"
implementation "org.springframework:spring-webmvc:6.2.7"
implementation("io.github.pixee:java-security-toolkit:1.2.1")
@ -458,7 +459,7 @@ dependencies {
implementation "org.springframework.boot:spring-boot-starter-mail:$springBootVersion"
implementation "org.springframework.session:spring-session-core:3.4.3"
implementation "org.springframework:spring-jdbc:6.2.6"
implementation "org.springframework:spring-jdbc:6.2.7"
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
// Don't upgrade h2database
@ -479,7 +480,7 @@ dependencies {
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
// Batik
implementation "org.apache.xmlgraphics:batik-all:1.18"
implementation "org.apache.xmlgraphics:batik-all:1.19"
// TwelveMonkeys
runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
@ -527,7 +528,7 @@ dependencies {
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
implementation "io.micrometer:micrometer-core:1.14.6"
implementation "io.micrometer:micrometer-core:1.15.0"
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
// https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation "org.commonmark:commonmark:0.24.0"
@ -542,6 +543,10 @@ dependencies {
compileOnly "org.projectlombok:lombok:$lombokVersion"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
// Mockito (core)
testImplementation 'org.mockito:mockito-core:5.17.0'
testRuntimeOnly 'org.mockito:mockito-inline:5.2.0'
}

View File

@ -1,5 +1,5 @@
plugins {
// Apply the foojay-resolver plugin to allow automatic download of JDKs
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.10.0'
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}
rootProject.name = 'Stirling-PDF'

View File

@ -61,6 +61,7 @@ public class EEAppConfig {
}
// TODO: Remove post migration
@SuppressWarnings("deprecation")
public void migrateEnterpriseSettingsToPremium(ApplicationProperties applicationProperties) {
EnterpriseEdition enterpriseEdition = applicationProperties.getEnterpriseEdition();
Premium premium = applicationProperties.getPremium();

View File

@ -48,30 +48,47 @@ public class KeygenLicenseVerifier {
private static final ObjectMapper objectMapper = new ObjectMapper();
private final ApplicationProperties applicationProperties;
// Shared HTTP client for connection pooling
private static final HttpClient httpClient =
HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(java.time.Duration.ofSeconds(10))
.build();
// License metadata context class to avoid shared mutable state
private static class LicenseContext {
private boolean isFloatingLicense = false;
private int maxMachines = 1; // Default to 1 if not specified
private boolean isEnterpriseLicense = false;
public LicenseContext() {}
}
public License verifyLicense(String licenseKeyOrCert) {
License license;
LicenseContext context = new LicenseContext();
if (isCertificateLicense(licenseKeyOrCert)) {
log.info("Detected certificate-based license. Processing...");
boolean isValid = verifyCertificateLicense(licenseKeyOrCert);
boolean isValid = verifyCertificateLicense(licenseKeyOrCert, context);
if (isValid) {
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
license = context.isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
} else {
license = License.NORMAL;
}
} else if (isJWTLicense(licenseKeyOrCert)) {
log.info("Detected JWT-style license key. Processing...");
boolean isValid = verifyJWTLicense(licenseKeyOrCert);
boolean isValid = verifyJWTLicense(licenseKeyOrCert, context);
if (isValid) {
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
license = context.isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
} else {
license = License.NORMAL;
}
} else {
log.info("Detected standard license key. Processing...");
boolean isValid = verifyStandardLicense(licenseKeyOrCert);
boolean isValid = verifyStandardLicense(licenseKeyOrCert, context);
if (isValid) {
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
license = context.isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
} else {
license = License.NORMAL;
}
@ -79,7 +96,7 @@ public class KeygenLicenseVerifier {
return license;
}
private boolean isEnterpriseLicense = false;
// Removed instance field for isEnterpriseLicense, now using LicenseContext
private boolean isCertificateLicense(String license) {
return license != null && license.trim().startsWith(CERT_PREFIX);
@ -89,7 +106,7 @@ public class KeygenLicenseVerifier {
return license != null && license.trim().startsWith(JWT_PREFIX);
}
private boolean verifyCertificateLicense(String licenseFile) {
private boolean verifyCertificateLicense(String licenseFile, LicenseContext context) {
try {
String encodedPayload = licenseFile;
// Remove the header
@ -144,7 +161,7 @@ public class KeygenLicenseVerifier {
}
// Process the certificate data
boolean isValid = processCertificateData(decodedData);
boolean isValid = processCertificateData(decodedData, context);
return isValid;
} catch (Exception e) {
@ -187,7 +204,7 @@ public class KeygenLicenseVerifier {
}
}
private boolean processCertificateData(String certData) {
private boolean processCertificateData(String certData, LicenseContext context) {
try {
JSONObject licenseData = new JSONObject(certData);
JSONObject metaObj = licenseData.optJSONObject("meta");
@ -229,15 +246,17 @@ public class KeygenLicenseVerifier {
if (attributesObj != null) {
log.info("Found attributes in certificate data");
// Check for floating license
context.isFloatingLicense = attributesObj.optBoolean("floating", false);
context.maxMachines = attributesObj.optInt("maxMachines", 1);
// Extract metadata
JSONObject metadataObj = attributesObj.optJSONObject("metadata");
if (metadataObj != null) {
int users = metadataObj.optInt("users", 0);
if (users > 0) {
applicationProperties.getPremium().setMaxUsers(users);
log.info("License allows for {} users", users);
}
isEnterpriseLicense = metadataObj.optBoolean("isEnterprise", false);
int users = metadataObj.optInt("users", 1);
applicationProperties.getPremium().setMaxUsers(users);
log.info("License allows for {} users", users);
context.isEnterpriseLicense = metadataObj.optBoolean("isEnterprise", false);
}
// Check license status if available
@ -257,7 +276,7 @@ public class KeygenLicenseVerifier {
}
}
private boolean verifyJWTLicense(String licenseKey) {
private boolean verifyJWTLicense(String licenseKey, LicenseContext context) {
try {
log.info("Verifying ED25519_SIGN format license key");
@ -291,7 +310,7 @@ public class KeygenLicenseVerifier {
String payload = new String(payloadBytes);
// Process the license payload
boolean isValid = processJWTLicensePayload(payload);
boolean isValid = processJWTLicensePayload(payload, context);
return isValid;
} catch (Exception e) {
@ -327,7 +346,7 @@ public class KeygenLicenseVerifier {
}
}
private boolean processJWTLicensePayload(String payload) {
private boolean processJWTLicensePayload(String payload, LicenseContext context) {
try {
log.info("Processing license payload: {}", payload);
@ -348,6 +367,13 @@ public class KeygenLicenseVerifier {
String licenseId = licenseObj.optString("id", "unknown");
log.info("Processing license with ID: {}", licenseId);
// Check for floating license in license object
context.isFloatingLicense = licenseObj.optBoolean("floating", false);
context.maxMachines = licenseObj.optInt("maxMachines", 1);
if (context.isFloatingLicense) {
log.info("Detected floating license with max machines: {}", context.maxMachines);
}
// Check expiry date
String expiryStr = licenseObj.optString("expiry", null);
if (expiryStr != null && !"null".equals(expiryStr)) {
@ -383,9 +409,22 @@ public class KeygenLicenseVerifier {
String policyId = policyObj.optString("id", "unknown");
log.info("License uses policy: {}", policyId);
// Check for floating license in policy
boolean policyFloating = policyObj.optBoolean("floating", false);
int policyMaxMachines = policyObj.optInt("maxMachines", 1);
// Policy settings take precedence
if (policyFloating) {
context.isFloatingLicense = true;
context.maxMachines = policyMaxMachines;
log.info(
"Policy defines floating license with max machines: {}",
context.maxMachines);
}
// Extract max users and isEnterprise from policy or metadata
int users = policyObj.optInt("users", 0);
isEnterpriseLicense = policyObj.optBoolean("isEnterprise", false);
int users = policyObj.optInt("users", 1);
context.isEnterpriseLicense = policyObj.optBoolean("isEnterprise", false);
if (users > 0) {
applicationProperties.getPremium().setMaxUsers(users);
@ -399,7 +438,7 @@ public class KeygenLicenseVerifier {
log.info("License allows for {} users (from metadata)", users);
// Check for isEnterprise flag in metadata
isEnterpriseLicense = metadata.optBoolean("isEnterprise", false);
context.isEnterpriseLicense = metadata.optBoolean("isEnterprise", false);
} else {
// Default value
applicationProperties.getPremium().setMaxUsers(1);
@ -415,13 +454,13 @@ public class KeygenLicenseVerifier {
}
}
private boolean verifyStandardLicense(String licenseKey) {
private boolean verifyStandardLicense(String licenseKey, LicenseContext context) {
try {
log.info("Checking standard license key");
String machineFingerprint = generateMachineFingerprint();
// First, try to validate the license
JsonNode validationResponse = validateLicense(licenseKey, machineFingerprint);
JsonNode validationResponse = validateLicense(licenseKey, machineFingerprint, context);
if (validationResponse != null) {
boolean isValid = validationResponse.path("meta").path("valid").asBoolean();
String licenseId = validationResponse.path("data").path("id").asText();
@ -435,10 +474,11 @@ public class KeygenLicenseVerifier {
"License not activated for this machine. Attempting to"
+ " activate...");
boolean activated =
activateMachine(licenseKey, licenseId, machineFingerprint);
activateMachine(licenseKey, licenseId, machineFingerprint, context);
if (activated) {
// Revalidate after activation
validationResponse = validateLicense(licenseKey, machineFingerprint);
validationResponse =
validateLicense(licenseKey, machineFingerprint, context);
isValid =
validationResponse != null
&& validationResponse
@ -458,9 +498,8 @@ public class KeygenLicenseVerifier {
}
}
private JsonNode validateLicense(String licenseKey, String machineFingerprint)
throws Exception {
HttpClient client = HttpClient.newHttpClient();
private JsonNode validateLicense(
String licenseKey, String machineFingerprint, LicenseContext context) throws Exception {
String requestBody =
String.format(
"{\"meta\":{\"key\":\"%s\",\"scope\":{\"fingerprint\":\"%s\"}}}",
@ -479,7 +518,8 @@ public class KeygenLicenseVerifier {
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.info("ValidateLicenseResponse body: {}", response.body());
JsonNode jsonResponse = objectMapper.readTree(response.body());
if (response.statusCode() == 200) {
@ -493,18 +533,61 @@ public class KeygenLicenseVerifier {
log.info("Validation detail: " + detail);
log.info("Validation code: " + code);
// Extract user count
// Check if the license itself has floating attribute
JsonNode licenseAttrs = jsonResponse.path("data").path("attributes");
if (!licenseAttrs.isMissingNode()) {
context.isFloatingLicense = licenseAttrs.path("floating").asBoolean(false);
context.maxMachines = licenseAttrs.path("maxMachines").asInt(1);
log.info(
"License floating (from license): {}, maxMachines: {}",
context.isFloatingLicense,
context.maxMachines);
}
// Also check the policy for floating license support if included
JsonNode includedNode = jsonResponse.path("included");
JsonNode policyNode = null;
if (includedNode.isArray()) {
for (JsonNode node : includedNode) {
if ("policies".equals(node.path("type").asText())) {
policyNode = node;
break;
}
}
}
if (policyNode != null) {
// Check if this is a floating license from policy
boolean policyFloating =
policyNode.path("attributes").path("floating").asBoolean(false);
int policyMaxMachines = policyNode.path("attributes").path("maxMachines").asInt(1);
// Policy takes precedence over license attributes
if (policyFloating) {
context.isFloatingLicense = true;
context.maxMachines = policyMaxMachines;
}
log.info(
"License floating (from policy): {}, maxMachines: {}",
context.isFloatingLicense,
context.maxMachines);
}
// Extract user count, default to 1 if not specified
int users =
jsonResponse
.path("data")
.path("attributes")
.path("metadata")
.path("users")
.asInt(0);
.asInt(1);
applicationProperties.getPremium().setMaxUsers(users);
// Extract isEnterprise flag
isEnterpriseLicense =
context.isEnterpriseLicense =
jsonResponse
.path("data")
.path("attributes")
@ -520,10 +603,105 @@ public class KeygenLicenseVerifier {
return jsonResponse;
}
private boolean activateMachine(String licenseKey, String licenseId, String machineFingerprint)
private boolean activateMachine(
String licenseKey, String licenseId, String machineFingerprint, LicenseContext context)
throws Exception {
HttpClient client = HttpClient.newHttpClient();
// For floating licenses, we first need to check if we need to deregister any machines
if (context.isFloatingLicense) {
log.info(
"Processing floating license activation. Max machines allowed: {}",
context.maxMachines);
// Get the current machines for this license
JsonNode machinesResponse = fetchMachinesForLicense(licenseKey, licenseId);
if (machinesResponse != null) {
JsonNode machines = machinesResponse.path("data");
int currentMachines = machines.size();
log.info(
"Current machine count: {}, Max allowed: {}",
currentMachines,
context.maxMachines);
// Check if the current fingerprint is already activated
boolean isCurrentMachineActivated = false;
String currentMachineId = null;
for (JsonNode machine : machines) {
if (machineFingerprint.equals(
machine.path("attributes").path("fingerprint").asText())) {
isCurrentMachineActivated = true;
currentMachineId = machine.path("id").asText();
log.info(
"Current machine is already activated with ID: {}",
currentMachineId);
break;
}
}
// If the current machine is already activated, there's no need to do anything
if (isCurrentMachineActivated) {
log.info("Machine already activated. No action needed.");
return true;
}
// If we've reached the max machines limit, we need to deregister the oldest machine
if (currentMachines >= context.maxMachines) {
log.info(
"Max machines reached. Deregistering oldest machine to make room for the new machine.");
// Find the oldest machine based on creation timestamp
if (machines.size() > 0) {
// Find the machine with the oldest creation date
String oldestMachineId = null;
java.time.Instant oldestTime = null;
for (JsonNode machine : machines) {
String createdStr =
machine.path("attributes").path("created").asText(null);
if (createdStr != null && !createdStr.isEmpty()) {
try {
java.time.Instant createdTime =
java.time.Instant.parse(createdStr);
if (oldestTime == null || createdTime.isBefore(oldestTime)) {
oldestTime = createdTime;
oldestMachineId = machine.path("id").asText();
}
} catch (Exception e) {
log.warn(
"Could not parse creation time for machine: {}",
e.getMessage());
}
}
}
// If we couldn't determine the oldest by timestamp, use the first one
if (oldestMachineId == null) {
log.warn(
"Could not determine oldest machine by timestamp, using first machine in list");
oldestMachineId = machines.path(0).path("id").asText();
}
log.info("Deregistering machine with ID: {}", oldestMachineId);
boolean deregistered = deregisterMachine(licenseKey, oldestMachineId);
if (!deregistered) {
log.error(
"Failed to deregister machine. Cannot proceed with activation.");
return false;
}
log.info(
"Machine deregistered successfully. Proceeding with activation of new machine.");
} else {
log.error(
"License has reached machine limit but no machines were found to deregister. This is unexpected.");
// We'll still try to activate, but it might fail
}
}
}
}
// Proceed with machine activation
String hostname;
try {
hostname = java.net.InetAddress.getLocalHost().getHostName();
@ -570,7 +748,8 @@ public class KeygenLicenseVerifier {
.POST(HttpRequest.BodyPublishers.ofString(body.toString()))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.info("activateMachine Response body: " + response.body());
if (response.statusCode() == 201) {
log.info("Machine activated successfully");
@ -588,4 +767,81 @@ public class KeygenLicenseVerifier {
private String generateMachineFingerprint() {
return GeneralUtils.generateMachineFingerprint();
}
/**
* Fetches all machines associated with a specific license
*
* @param licenseKey The license key to check
* @param licenseId The license ID
* @return JsonNode containing the list of machines, or null if an error occurs
* @throws Exception if an error occurs during the HTTP request
*/
private JsonNode fetchMachinesForLicense(String licenseKey, String licenseId) throws Exception {
HttpRequest request =
HttpRequest.newBuilder()
.uri(
URI.create(
BASE_URL
+ "/"
+ ACCOUNT_ID
+ "/licenses/"
+ licenseId
+ "/machines"))
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.header("Authorization", "License " + licenseKey)
.GET()
.build();
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.info("fetchMachinesForLicense Response body: {}", response.body());
if (response.statusCode() == 200) {
return objectMapper.readTree(response.body());
} else {
log.error(
"Error fetching machines for license. Status code: {}, error: {}",
response.statusCode(),
response.body());
return null;
}
}
/**
* Deregisters a machine from a license
*
* @param licenseKey The license key
* @param machineId The ID of the machine to deregister
* @return true if deregistration was successful, false otherwise
*/
private boolean deregisterMachine(String licenseKey, String machineId) {
try {
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/" + ACCOUNT_ID + "/machines/" + machineId))
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.header("Authorization", "License " + licenseKey)
.DELETE()
.build();
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 204) {
log.info("Machine {} successfully deregistered", machineId);
return true;
} else {
log.error(
"Error deregistering machine. Status code: {}, error: {}",
response.statusCode(),
response.body());
return false;
}
} catch (Exception e) {
log.error("Exception during machine deregistration: {}", e.getMessage(), e);
return false;
}
}
}

View File

@ -31,7 +31,8 @@ public class LibreOfficeListener {
log.info("waiting for listener to start");
try (Socket socket = new Socket()) {
socket.connect(
new InetSocketAddress("localhost", 2002), 1000); // Timeout after 1 second
new InetSocketAddress("localhost", LISTENER_PORT),
1000); // Timeout after 1 second
return true;
} catch (Exception e) {
return false;

View File

@ -11,8 +11,11 @@ import org.thymeleaf.templateresolver.AbstractConfigurableTemplateResolver;
import org.thymeleaf.templateresource.FileTemplateResource;
import org.thymeleaf.templateresource.ITemplateResource;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.InputStreamTemplateResource;
@Slf4j
public class FileFallbackTemplateResolver extends AbstractConfigurableTemplateResolver {
private final ResourceLoader resourceLoader;
@ -40,7 +43,8 @@ public class FileFallbackTemplateResolver extends AbstractConfigurableTemplateRe
return new FileTemplateResource(resource.getFile().getPath(), characterEncoding);
}
} catch (IOException e) {
// Log the exception to help with debugging issues loading external templates
log.warn("Unable to read template '{}' from file system", resourceName, e);
}
InputStream inputStream =

View File

@ -73,7 +73,7 @@ public class InitialSetup {
// Initialize Terms and Conditions
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
if (StringUtils.isEmpty(termsUrl)) {
String defaultTermsUrl = "https://www.stirlingpdf.com/terms-and-conditions";
String defaultTermsUrl = "https://www.stirlingpdf.com/terms";
GeneralUtils.saveKeyToSettings("legal.termsAndConditions", defaultTermsUrl);
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
}

View File

@ -15,7 +15,7 @@ public class MetricsConfig {
return new MeterFilter() {
@Override
public MeterFilterReply accept(Meter.Id id) {
if (id.getName().equals("http.requests")) {
if ("http.requests".equals(id.getName())) {
return MeterFilterReply.NEUTRAL;
}
return MeterFilterReply.DENY;

View File

@ -5,7 +5,9 @@ import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
@ -31,14 +33,25 @@ public class OpenApiConfig {
// default version if all else fails
version = "1.0.0";
}
Info info =
new Info()
.title(DEFAULT_TITLE)
.version(version)
.license(
new License()
.name("MIT")
.url(
"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/LICENSE")
.identifier("MIT"))
.termsOfService("https://www.stirlingpdf.com/terms")
.contact(
new Contact()
.name("Stirling Software")
.url("https://www.stirlingpdf.com")
.email("contact@stirlingpdf.com"))
.description(DEFAULT_DESCRIPTION);
if (!applicationProperties.getSecurity().getEnableLogin()) {
return new OpenAPI()
.components(new Components())
.info(
new Info()
.title(DEFAULT_TITLE)
.version(version)
.description(DEFAULT_DESCRIPTION));
return new OpenAPI().components(new Components()).info(info);
} else {
SecurityScheme apiKeyScheme =
new SecurityScheme()
@ -47,11 +60,7 @@ public class OpenApiConfig {
.name("X-API-KEY");
return new OpenAPI()
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
.info(
new Info()
.title(DEFAULT_TITLE)
.version(version)
.description(DEFAULT_DESCRIPTION))
.info(info)
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
}
}

View File

@ -59,7 +59,8 @@ public class AnalysisController {
description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO")
public Map<String, String> getDocumentProperties(@ModelAttribute PDFFile file)
throws IOException {
// Load the document in read-only mode to prevent modifications and ensure the integrity of the original file.
// Load the document in read-only mode to prevent modifications and ensure the integrity of
// the original file.
try (PDDocument document = pdfDocumentFactory.load(file.getFileInput(), true)) {
PDDocumentInformation info = document.getDocumentInformation();
Map<String, String> properties = new HashMap<>();
@ -180,7 +181,8 @@ public class AnalysisController {
// Get permissions
Map<String, Boolean> permissions = new HashMap<>();
permissions.put("preventPrinting", !document.getCurrentAccessPermission().canPrint());
permissions.put(
"preventPrinting", !document.getCurrentAccessPermission().canPrint());
permissions.put(
"preventModify", !document.getCurrentAccessPermission().canModify());
permissions.put(

View File

@ -39,8 +39,8 @@ public class CropController {
description =
"This operation takes an input PDF file and crops it according to the given"
+ " coordinates. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> cropPdf(@ModelAttribute CropPdfForm form) throws IOException {
PDDocument sourceDocument = pdfDocumentFactory.load(form);
public ResponseEntity<byte[]> cropPdf(@ModelAttribute CropPdfForm request) throws IOException {
PDDocument sourceDocument = pdfDocumentFactory.load(request);
PDDocument newDocument =
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
@ -64,7 +64,8 @@ public class CropController {
contentStream.saveGraphicsState();
// Define the crop area
contentStream.addRect(form.getX(), form.getY(), form.getWidth(), form.getHeight());
contentStream.addRect(
request.getX(), request.getY(), request.getWidth(), request.getHeight());
contentStream.clip();
// Draw the entire formXObject
@ -76,7 +77,11 @@ public class CropController {
// Now, set the new page's media box to the cropped size
newPage.setMediaBox(
new PDRectangle(form.getX(), form.getY(), form.getWidth(), form.getHeight()));
new PDRectangle(
request.getX(),
request.getY(),
request.getWidth(),
request.getHeight()));
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -87,7 +92,7 @@ public class CropController {
byte[] pdfContent = baos.toByteArray();
return WebResponseUtils.bytesToWebResponse(
pdfContent,
form.getFileInput().getOriginalFilename().replaceFirst("[.][^.]+$", "")
request.getFileInput().getOriginalFilename().replaceFirst("[.][^.]+$", "")
+ "_cropped.pdf");
}
}

View File

@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.mail.MessagingException;
@ -41,7 +42,13 @@ public class EmailController {
* @return ResponseEntity with success or error message.
*/
@PostMapping(consumes = "multipart/form-data", value = "/send-email")
@Operation(
summary = "Send an email with an attachment",
description =
"This endpoint sends an email with an attachment. Input:PDF"
+ " Output:Success/Failure Type:MISO")
public ResponseEntity<String> sendEmailWithAttachment(@Valid @ModelAttribute Email email) {
log.info("Sending email to: {}", email.toString());
try {
// Calls the service to send the email with attachment
emailService.sendEmailWithAttachment(email);

View File

@ -117,20 +117,20 @@ public class MergeController {
"This endpoint merges multiple PDF files into a single PDF file. The merged"
+ " file will contain all pages from the input files in the order they were"
+ " provided. Input:PDF Output:PDF Type:MISO")
public ResponseEntity<byte[]> mergePdfs(@ModelAttribute MergePdfsRequest form)
public ResponseEntity<byte[]> mergePdfs(@ModelAttribute MergePdfsRequest request)
throws IOException {
List<File> filesToDelete = new ArrayList<>(); // List of temporary files to delete
File mergedTempFile = null;
PDDocument mergedDocument = null;
boolean removeCertSign = form.isRemoveCertSign();
boolean removeCertSign = Boolean.TRUE.equals(request.getRemoveCertSign());
try {
MultipartFile[] files = form.getFileInput();
MultipartFile[] files = request.getFileInput();
Arrays.sort(
files,
getSortComparator(
form.getSortType())); // Sort files based on the given sort type
request.getSortType())); // Sort files based on the given sort type
PDFMergerUtility mergerUtility = new PDFMergerUtility();
long totalSize = 0;

View File

@ -47,7 +47,7 @@ public class MultiPageLayoutController {
int pagesPerSheet = request.getPagesPerSheet();
MultipartFile file = request.getFileInput();
boolean addBorder = request.isAddBorder();
boolean addBorder = Boolean.TRUE.equals(request.getAddBorder());
if (pagesPerSheet != 2
&& pagesPerSheet != 3

View File

@ -127,7 +127,7 @@ public class SplitPdfByChaptersController {
Path zipFile = null;
try {
boolean includeMetadata = request.getIncludeMetadata();
boolean includeMetadata = Boolean.TRUE.equals(request.getIncludeMetadata());
Integer bookmarkLevel =
request.getBookmarkLevel(); // levels start from 0 (top most bookmarks)
if (bookmarkLevel < 0) {
@ -161,7 +161,7 @@ public class SplitPdfByChaptersController {
.body("Unable to extract outline items".getBytes());
}
boolean allowDuplicates = request.getAllowDuplicates();
boolean allowDuplicates = Boolean.TRUE.equals(request.getAllowDuplicates());
if (!allowDuplicates) {
/*
duplicates are generated when multiple bookmarks correspond to the same page,

View File

@ -60,7 +60,7 @@ public class SplitPdfBySectionsController {
// Process the PDF based on split parameters
int horiz = request.getHorizontalDivisions() + 1;
int verti = request.getVerticalDivisions() + 1;
boolean merge = request.isMerge();
boolean merge = Boolean.TRUE.equals(request.getMerge());
List<PDDocument> splitDocuments = splitPdfPages(sourceDocument, verti, horiz);
String filename =

View File

@ -3,7 +3,6 @@ package stirling.software.SPDF.controller.api;
import java.io.IOException;
import java.security.Principal;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -168,13 +167,23 @@ public class UserController {
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/updateUserSettings")
public String updateUserSettings(HttpServletRequest request, Principal principal)
/**
* Updates the user settings based on the provided JSON payload.
*
* @param updates A map containing the settings to update. The expected structure is:
* <ul>
* <li><b>emailNotifications</b> (optional): "true" or "false" - Enable or disable email notifications.</li>
* <li><b>theme</b> (optional): "light" or "dark" - Set the user's preferred theme.</li>
* <li><b>language</b> (optional): A string representing the preferred language (e.g., "en", "fr").</li>
* </ul>
* Keys not listed above will be ignored.
* @param principal The currently authenticated user.
* @return A redirect string to the account page after updating the settings.
* @throws SQLException If a database error occurs.
* @throws UnsupportedProviderException If the operation is not supported for the user's provider.
*/
public String updateUserSettings(@RequestBody Map<String, String> updates, Principal principal)
throws SQLException, UnsupportedProviderException {
Map<String, String[]> paramMap = request.getParameterMap();
Map<String, String> updates = new HashMap<>();
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
updates.put(entry.getKey(), entry.getValue()[0]);
}
log.debug("Processed updates: {}", updates);
// Assuming you have a method in userService to update the settings for a user
userService.updateUserSettings(principal.getName(), updates);

View File

@ -58,7 +58,7 @@ public class ConvertImgPDFController {
String imageFormat = request.getImageFormat();
String singleOrMultiple = request.getSingleOrMultiple();
String colorType = request.getColorType();
String dpi = request.getDpi();
int dpi = request.getDpi();
String pageNumbers = request.getPageNumbers();
Path tempFile = null;
Path tempOutputDir = null;
@ -94,7 +94,7 @@ public class ConvertImgPDFController {
: imageFormat.toUpperCase(),
colorTypeResult,
singleImage,
Integer.valueOf(dpi),
dpi,
filename);
if (result == null || result.length == 0) {
log.error("resultant bytes for {} is null, error converting ", filename);
@ -132,7 +132,7 @@ public class ConvertImgPDFController {
command.add(tempOutputDir.toString());
}
command.add("--dpi");
command.add(dpi);
command.add(String.valueOf(dpi));
ProcessExecutorResult resultProcess =
ProcessExecutor.getInstance(ProcessExecutor.Processes.PYTHON_OPENCV)
.runCommandWithOutputHandling(command);
@ -213,7 +213,7 @@ public class ConvertImgPDFController {
MultipartFile[] file = request.getFileInput();
String fitOption = request.getFitOption();
String colorType = request.getColorType();
boolean autoRotate = request.isAutoRotate();
boolean autoRotate = Boolean.TRUE.equals(request.getAutoRotate());
// Handle Null entries for formdata
if (colorType == null || colorType.isBlank()) {
colorType = "color";

View File

@ -47,9 +47,9 @@ public class ConvertMarkdownToPdf {
description =
"This endpoint takes a Markdown file input, converts it to HTML, and then to"
+ " PDF format. Input:MARKDOWN Output:PDF Type:SISO")
public ResponseEntity<byte[]> markdownToPdf(@ModelAttribute GeneralFile request)
public ResponseEntity<byte[]> markdownToPdf(@ModelAttribute GeneralFile generalFile)
throws Exception {
MultipartFile fileInput = request.getFileInput();
MultipartFile fileInput = generalFile.getFileInput();
if (fileInput == null) {
throw new IllegalArgumentException("Please provide a Markdown file for conversion.");

View File

@ -90,9 +90,9 @@ public class ConvertOfficeController {
description =
"This endpoint converts a given file to a PDF using LibreOffice API Input:ANY"
+ " Output:PDF Type:SISO")
public ResponseEntity<byte[]> processFileToPDF(@ModelAttribute GeneralFile request)
public ResponseEntity<byte[]> processFileToPDF(@ModelAttribute GeneralFile generalFile)
throws Exception {
MultipartFile inputFile = request.getFileInput();
MultipartFile inputFile = generalFile.getFileInput();
// unused but can start server instance if startup time is to long
// LibreOfficeListener.getInstance().start();
File file = null;

View File

@ -23,9 +23,8 @@ public class ConvertPDFToHtml {
summary = "Convert PDF to HTML",
description =
"This endpoint converts a PDF file to HTML format. Input:PDF Output:HTML Type:SISO")
public ResponseEntity<byte[]> processPdfToHTML(@ModelAttribute PDFFile request)
throws Exception {
MultipartFile inputFile = request.getFileInput();
public ResponseEntity<byte[]> processPdfToHTML(@ModelAttribute PDFFile file) throws Exception {
MultipartFile inputFile = file.getFileInput();
PDFToFile pdfToFile = new PDFToFile();
return pdfToFile.processPdfToHtml(inputFile);
}

View File

@ -97,9 +97,8 @@ public class ConvertPDFToOffice {
description =
"This endpoint converts a PDF file to an XML file. Input:PDF Output:XML"
+ " Type:SISO")
public ResponseEntity<byte[]> processPdfToXML(@ModelAttribute PDFFile request)
throws Exception {
MultipartFile inputFile = request.getFileInput();
public ResponseEntity<byte[]> processPdfToXML(@ModelAttribute PDFFile file) throws Exception {
MultipartFile inputFile = file.getFileInput();
PDFToFile pdfToFile = new PDFToFile();
return pdfToFile.processPdfToOfficeFormat(inputFile, "xml", "writer_pdf_import");

View File

@ -52,12 +52,12 @@ public class ExtractCSVController {
description =
"This operation takes an input PDF file and returns CSV file of whole page."
+ " Input:PDF Output:CSV Type:SISO")
public ResponseEntity<?> pdfToCsv(@ModelAttribute PDFWithPageNums form) throws Exception {
String baseName = getBaseName(form.getFileInput().getOriginalFilename());
public ResponseEntity<?> pdfToCsv(@ModelAttribute PDFWithPageNums request) throws Exception {
String baseName = getBaseName(request.getFileInput().getOriginalFilename());
List<CsvEntry> csvEntries = new ArrayList<>();
try (PDDocument document = pdfDocumentFactory.load(form)) {
List<Integer> pages = form.getPageNumbersList(document, true);
try (PDDocument document = pdfDocumentFactory.load(request)) {
List<Integer> pages = request.getPageNumbersList(document, true);
SpreadsheetExtractionAlgorithm sea = new SpreadsheetExtractionAlgorithm();
CSVFormat format =
CSVFormat.EXCEL.builder().setEscape('"').setQuoteMode(QuoteMode.ALL).build();

View File

@ -77,7 +77,7 @@ public class FilterController {
public ResponseEntity<byte[]> pageCount(@ModelAttribute PDFComparisonAndCount request)
throws IOException, InterruptedException {
MultipartFile inputFile = request.getFileInput();
String pageCount = request.getPageCount();
int pageCount = request.getPageCount();
String comparator = request.getComparator();
// Load the PDF
PDDocument document = pdfDocumentFactory.load(inputFile);
@ -87,13 +87,13 @@ public class FilterController {
// Perform the comparison
switch (comparator) {
case "Greater":
valid = actualPageCount > Integer.parseInt(pageCount);
valid = actualPageCount > pageCount;
break;
case "Equal":
valid = actualPageCount == Integer.parseInt(pageCount);
valid = actualPageCount == pageCount;
break;
case "Less":
valid = actualPageCount < Integer.parseInt(pageCount);
valid = actualPageCount < pageCount;
break;
default:
throw new IllegalArgumentException("Invalid comparator: " + comparator);
@ -153,7 +153,7 @@ public class FilterController {
public ResponseEntity<byte[]> fileSize(@ModelAttribute FileSizeRequest request)
throws IOException, InterruptedException {
MultipartFile inputFile = request.getFileInput();
String fileSize = request.getFileSize();
long fileSize = request.getFileSize();
String comparator = request.getComparator();
// Get the file size
@ -163,13 +163,13 @@ public class FilterController {
// Perform the comparison
switch (comparator) {
case "Greater":
valid = actualFileSize > Long.parseLong(fileSize);
valid = actualFileSize > fileSize;
break;
case "Equal":
valid = actualFileSize == Long.parseLong(fileSize);
valid = actualFileSize == fileSize;
break;
case "Less":
valid = actualFileSize < Long.parseLong(fileSize);
valid = actualFileSize < fileSize;
break;
default:
throw new IllegalArgumentException("Invalid comparator: " + comparator);

View File

@ -47,7 +47,7 @@ public class AutoRenameController {
public ResponseEntity<byte[]> extractHeader(@ModelAttribute ExtractHeaderRequest request)
throws Exception {
MultipartFile file = request.getFileInput();
Boolean useFirstTextAsFallback = request.isUseFirstTextAsFallback();
boolean useFirstTextAsFallback = Boolean.TRUE.equals(request.getUseFirstTextAsFallback());
PDDocument document = pdfDocumentFactory.load(file);
PDFTextStripper reader =

View File

@ -113,7 +113,7 @@ public class AutoSplitPdfController {
public ResponseEntity<byte[]> autoSplitPdf(@ModelAttribute AutoSplitPdfRequest request)
throws IOException {
MultipartFile file = request.getFileInput();
boolean duplexMode = request.isDuplexMode();
boolean duplexMode = Boolean.TRUE.equals(request.getDuplexMode());
PDDocument document = null;
List<PDDocument> splitDocuments = new ArrayList<>();

View File

@ -626,32 +626,32 @@ public class CompressController {
// Scale factors for different optimization levels
private double getScaleFactorForLevel(int optimizeLevel) {
return switch (optimizeLevel) {
case 3 -> 0.85;
case 4 -> 0.75;
case 5 -> 0.65;
case 6 -> 0.55;
case 7 -> 0.45;
case 8 -> 0.35;
case 9 -> 0.25;
case 10 -> 0.15;
default -> 1.0;
};
return switch (optimizeLevel) {
case 3 -> 0.85;
case 4 -> 0.75;
case 5 -> 0.65;
case 6 -> 0.55;
case 7 -> 0.45;
case 8 -> 0.35;
case 9 -> 0.25;
case 10 -> 0.15;
default -> 1.0;
};
}
// JPEG quality for different optimization levels
private float getJpegQualityForLevel(int optimizeLevel) {
return switch (optimizeLevel) {
case 3 -> 0.85f;
case 4 -> 0.80f;
case 5 -> 0.75f;
case 6 -> 0.70f;
case 7 -> 0.60f;
case 8 -> 0.50f;
case 9 -> 0.35f;
case 10 -> 0.2f;
default -> 0.7f;
};
return switch (optimizeLevel) {
case 3 -> 0.85f;
case 4 -> 0.80f;
case 5 -> 0.75f;
case 6 -> 0.70f;
case 7 -> 0.60f;
case 8 -> 0.50f;
case 9 -> 0.35f;
case 10 -> 0.2f;
default -> 0.7f;
};
}
@PostMapping(consumes = "multipart/form-data", value = "/compress-pdf")

View File

@ -18,14 +18,13 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
@ -58,24 +57,11 @@ public class ExtractImageScansController {
+ " minimum contour area, and border size. Input:PDF Output:IMAGE/ZIP"
+ " Type:SIMO")
public ResponseEntity<byte[]> extractImageScans(
@RequestBody(
description = "Form data containing file and extraction parameters",
required = true,
content =
@Content(
mediaType = "multipart/form-data",
schema =
@Schema(
implementation =
ExtractImageScansRequest
.class) // This should
// represent
// your form's
// structure
))
ExtractImageScansRequest form)
@ModelAttribute ExtractImageScansRequest request)
throws IOException, InterruptedException {
String fileName = form.getFileInput().getOriginalFilename();
MultipartFile inputFile = request.getFileInput();
String fileName = inputFile.getOriginalFilename();
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
List<String> images = new ArrayList<>();
@ -94,7 +80,7 @@ public class ExtractImageScansController {
// Check if input file is a PDF
if ("pdf".equalsIgnoreCase(extension)) {
// Load PDF document
try (PDDocument document = pdfDocumentFactory.load(form.getFileInput())) {
try (PDDocument document = pdfDocumentFactory.load(inputFile)) {
PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true);
int pageCount = document.getNumberOfPages();
@ -116,7 +102,7 @@ public class ExtractImageScansController {
}
} else {
tempInputFile = Files.createTempFile("input_", "." + extension);
form.getFileInput().transferTo(tempInputFile);
inputFile.transferTo(tempInputFile);
// Add input file path to images list
images.add(tempInputFile.toString());
}
@ -136,15 +122,15 @@ public class ExtractImageScansController {
images.get(i),
tempDir.toString(),
"--angle_threshold",
String.valueOf(form.getAngleThreshold()),
String.valueOf(request.getAngleThreshold()),
"--tolerance",
String.valueOf(form.getTolerance()),
String.valueOf(request.getTolerance()),
"--min_area",
String.valueOf(form.getMinArea()),
String.valueOf(request.getMinArea()),
"--min_contour_area",
String.valueOf(form.getMinContourArea()),
String.valueOf(request.getMinContourArea()),
"--border_size",
String.valueOf(form.getBorderSize())));
String.valueOf(request.getBorderSize())));
// Run CLI command
ProcessExecutorResult returnCode =

View File

@ -64,7 +64,7 @@ public class ExtractImagesController {
throws IOException, InterruptedException, ExecutionException {
MultipartFile file = request.getFileInput();
String format = request.getFormat();
boolean allowDuplicates = request.isAllowDuplicates();
boolean allowDuplicates = Boolean.TRUE.equals(request.getAllowDuplicates());
PDDocument document = pdfDocumentFactory.load(file);
// Determine if multithreading should be used based on PDF size or number of pages

View File

@ -65,7 +65,7 @@ public class MetadataController {
MultipartFile pdfFile = request.getFileInput();
// Extract metadata information
Boolean deleteAll = request.isDeleteAll();
boolean deleteAll = Boolean.TRUE.equals(request.getDeleteAll());
String author = request.getAuthor();
String creationDate = request.getCreationDate();
String creator = request.getCreator();

View File

@ -43,7 +43,7 @@ public class OverlayImageController {
MultipartFile imageFile = request.getImageFile();
float x = request.getX();
float y = request.getY();
boolean everyPage = request.isEveryPage();
boolean everyPage = Boolean.TRUE.equals(request.getEveryPage());
try {
byte[] pdfBytes = pdfFile.getBytes();
byte[] imageBytes = imageFile.getBytes();

View File

@ -49,33 +49,30 @@ public class PageNumbersController {
MultipartFile file = request.getFileInput();
String customMargin = request.getCustomMargin();
int position = request.getPosition();
int startingNumber = request.getStartingNumber();
int pageNumber = request.getStartingNumber();
String pagesToNumber = request.getPagesToNumber();
String customText = request.getCustomText();
int pageNumber = startingNumber;
float fontSize = request.getFontSize();
String fontType = request.getFontType();
PDDocument document = pdfDocumentFactory.load(file);
float font_size = request.getFontSize();
String font_type = request.getFontType();
float marginFactor;
switch (customMargin.toLowerCase()) {
case "small":
marginFactor = 0.02f;
break;
case "medium":
marginFactor = 0.035f;
break;
case "large":
marginFactor = 0.05f;
break;
case "x-large":
marginFactor = 0.075f;
break;
case "medium":
default:
marginFactor = 0.035f;
break;
}
float fontSize = font_size;
if (pagesToNumber == null || pagesToNumber.isEmpty()) {
pagesToNumber = "all";
}
@ -99,7 +96,7 @@ public class PageNumbersController {
.replaceFirst("[.][^.]+$", ""));
PDType1Font currentFont =
switch (font_type.toLowerCase()) {
switch (fontType.toLowerCase()) {
case "courier" -> new PDType1Font(Standard14Fonts.FontName.COURIER);
case "times" -> new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN);
default -> new PDType1Font(Standard14Fonts.FontName.HELVETICA);

View File

@ -40,9 +40,9 @@ public class RepairController {
"This endpoint repairs a given PDF file by running qpdf command. The PDF is"
+ " first saved to a temporary location, repaired, read back, and then"
+ " returned as a response. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> repairPdf(@ModelAttribute PDFFile request)
public ResponseEntity<byte[]> repairPdf(@ModelAttribute PDFFile file)
throws IOException, InterruptedException {
MultipartFile inputFile = request.getFileInput();
MultipartFile inputFile = file.getFileInput();
// Save the uploaded file to a temporary location
Path tempInputFile = Files.createTempFile("input_", ".pdf");
byte[] pdfBytes = null;

View File

@ -31,18 +31,18 @@ public class ReplaceAndInvertColorController {
@Operation(
summary = "Replace-Invert Color PDF",
description =
"This endpoint accepts a PDF file and option of invert all colors or replace text and background colors. Input:PDF Output:PDF Type:SISO")
"This endpoint accepts a PDF file and option of invert all colors or replace"
+ " text and background colors. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<InputStreamResource> replaceAndInvertColor(
@ModelAttribute ReplaceAndInvertColorRequest replaceAndInvertColorRequest)
throws IOException {
@ModelAttribute ReplaceAndInvertColorRequest request) throws IOException {
InputStreamResource resource =
replaceAndInvertColorService.replaceAndInvertColor(
replaceAndInvertColorRequest.getFileInput(),
replaceAndInvertColorRequest.getReplaceAndInvertOption(),
replaceAndInvertColorRequest.getHighContrastColorCombination(),
replaceAndInvertColorRequest.getBackGroundColor(),
replaceAndInvertColorRequest.getTextColor());
request.getFileInput(),
request.getReplaceAndInvertOption(),
request.getHighContrastColorCombination(),
request.getBackGroundColor(),
request.getTextColor());
// Return the modified PDF as a downloadable file
return ResponseEntity.ok()

View File

@ -36,8 +36,8 @@ public class ShowJavascript {
@Operation(
summary = "Grabs all JS from a PDF and returns a single JS file with all code",
description = "desc. Input:PDF Output:JS Type:SISO")
public ResponseEntity<byte[]> extractHeader(@ModelAttribute PDFFile request) throws Exception {
MultipartFile inputFile = request.getFileInput();
public ResponseEntity<byte[]> extractHeader(@ModelAttribute PDFFile file) throws Exception {
MultipartFile inputFile = file.getFileInput();
String script = "";
try (PDDocument document = pdfDocumentFactory.load(inputFile)) {

View File

@ -93,6 +93,7 @@ public class PipelineProcessor {
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
PrintStream logPrintStream = new PrintStream(logStream);
boolean hasErrors = false;
boolean filtersApplied = false;
for (PipelineOperation pipelineOperation : config.getOperations()) {
String operation = pipelineOperation.getOperation();
boolean isMultiInputOperation = apiDocService.isMultiInput(operation);
@ -134,7 +135,7 @@ public class PipelineProcessor {
if (operation.startsWith("filter-")
&& (response.getBody() == null
|| response.getBody().length == 0)) {
result.setFiltersApplied(true);
filtersApplied = true;
log.info("Skipping file due to filtering {}", operation);
continue;
}
@ -215,12 +216,12 @@ public class PipelineProcessor {
log.error("Errors occurred during processing. Log: {}", logStream.toString());
}
result.setHasErrors(hasErrors);
result.setFiltersApplied(hasErrors);
result.setFiltersApplied(filtersApplied);
result.setOutputFiles(outputFiles);
return result;
}
private ResponseEntity<byte[]> sendWebRequest(String url, MultiValueMap<String, Object> body) {
/* package */ ResponseEntity<byte[]> sendWebRequest(String url, MultiValueMap<String, Object> body) {
RestTemplate restTemplate = new RestTemplate();
// Set up headers, including API key
HttpHeaders headers = new HttpHeaders();

View File

@ -146,8 +146,8 @@ public class CertSignController {
summary = "Sign PDF with a Digital Certificate",
description =
"This endpoint accepts a PDF file, a digital certificate and related"
+ " information to sign the PDF. It then returns the digitally signed PDF"
+ " file. Input:PDF Output:PDF Type:SISO")
+ " information to sign the PDF. It then returns the digitally signed PDF"
+ " file. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request)
throws Exception {
MultipartFile pdf = request.getFileInput();

View File

@ -622,8 +622,8 @@ public class GetInfoOnPDF {
permissionsNode.put("Document Assembly", getPermissionState(ap.canAssembleDocument()));
permissionsNode.put("Extracting Content", getPermissionState(ap.canExtractContent()));
permissionsNode.put(
"Extracting for accessibility",
getPermissionState(ap.canExtractForAccessibility()));
"Extracting for accessibility",
getPermissionState(ap.canExtractForAccessibility()));
permissionsNode.put("Form Filling", getPermissionState(ap.canFillInForm()));
permissionsNode.put("Modifying", getPermissionState(ap.canModify()));
permissionsNode.put("Modifying annotations", getPermissionState(ap.canModifyAnnotations()));

View File

@ -63,14 +63,16 @@ public class PasswordController {
String ownerPassword = request.getOwnerPassword();
String password = request.getPassword();
int keyLength = request.getKeyLength();
boolean preventAssembly = request.isPreventAssembly();
boolean preventExtractContent = request.isPreventExtractContent();
boolean preventExtractForAccessibility = request.isPreventExtractForAccessibility();
boolean preventFillInForm = request.isPreventFillInForm();
boolean preventModify = request.isPreventModify();
boolean preventModifyAnnotations = request.isPreventModifyAnnotations();
boolean preventPrinting = request.isPreventPrinting();
boolean preventPrintingFaithful = request.isPreventPrintingFaithful();
boolean preventAssembly = Boolean.TRUE.equals(request.getPreventAssembly());
boolean preventExtractContent = Boolean.TRUE.equals(request.getPreventExtractContent());
boolean preventExtractForAccessibility =
Boolean.TRUE.equals(request.getPreventExtractForAccessibility());
boolean preventFillInForm = Boolean.TRUE.equals(request.getPreventFillInForm());
boolean preventModify = Boolean.TRUE.equals(request.getPreventModify());
boolean preventModifyAnnotations =
Boolean.TRUE.equals(request.getPreventModifyAnnotations());
boolean preventPrinting = Boolean.TRUE.equals(request.getPreventPrinting());
boolean preventPrintingFaithful = Boolean.TRUE.equals(request.getPreventPrintingFaithful());
PDDocument document = pdfDocumentFactory.load(fileInput);
AccessPermission ap = new AccessPermission();

View File

@ -75,7 +75,7 @@ public class RedactController {
redactPages(request, document, allPages);
redactAreas(redactionAreas, document, allPages);
if (request.isConvertPDFToImage()) {
if (Boolean.TRUE.equals(request.getConvertPDFToImage())) {
PDDocument convertedPdf = PdfUtils.convertPdfToPdfImage(document);
document.close();
document = convertedPdf;
@ -180,7 +180,6 @@ public class RedactController {
}
}
private List<Integer> getPageNumbers(ManualRedactPdfRequest request, int pagesCount) {
String pageNumbersInput = request.getPageNumbers();
String[] parsedPageNumbers =
@ -201,11 +200,11 @@ public class RedactController {
throws Exception {
MultipartFile file = request.getFileInput();
String listOfTextString = request.getListOfText();
boolean useRegex = request.isUseRegex();
boolean wholeWordSearchBool = request.isWholeWordSearch();
boolean useRegex = Boolean.TRUE.equals(request.getUseRegex());
boolean wholeWordSearchBool = Boolean.TRUE.equals(request.getWholeWordSearch());
String colorString = request.getRedactColor();
float customPadding = request.getCustomPadding();
boolean convertPDFToImage = request.isConvertPDFToImage();
boolean convertPDFToImage = Boolean.TRUE.equals(request.getConvertPDFToImage());
String[] listOfText = listOfTextString.split("\n");
PDDocument document = pdfDocumentFactory.load(file);

View File

@ -46,12 +46,12 @@ public class SanitizeController {
public ResponseEntity<byte[]> sanitizePDF(@ModelAttribute SanitizePdfRequest request)
throws IOException {
MultipartFile inputFile = request.getFileInput();
boolean removeJavaScript = request.isRemoveJavaScript();
boolean removeEmbeddedFiles = request.isRemoveEmbeddedFiles();
boolean removeXMPMetadata = request.isRemoveXMPMetadata();
boolean removeMetadata = request.isRemoveMetadata();
boolean removeLinks = request.isRemoveLinks();
boolean removeFonts = request.isRemoveFonts();
boolean removeJavaScript = Boolean.TRUE.equals(request.getRemoveJavaScript());
boolean removeEmbeddedFiles = Boolean.TRUE.equals(request.getRemoveEmbeddedFiles());
boolean removeXMPMetadata = Boolean.TRUE.equals(request.getRemoveXMPMetadata());
boolean removeMetadata = Boolean.TRUE.equals(request.getRemoveMetadata());
boolean removeLinks = Boolean.TRUE.equals(request.getRemoveLinks());
boolean removeFonts = Boolean.TRUE.equals(request.getRemoveFonts());
PDDocument document = pdfDocumentFactory.load(inputFile, true);
if (removeJavaScript) {

View File

@ -1,5 +1,6 @@
package stirling.software.SPDF.controller.api.security;
import java.beans.PropertyEditorSupport;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
@ -23,6 +24,8 @@ import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.util.Store;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -48,6 +51,18 @@ public class ValidateSignatureController {
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final CertificateValidationService certValidationService;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(
MultipartFile.class,
new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(null);
}
});
}
@Operation(
summary = "Validate PDF Digital Signature",
description =
@ -58,12 +73,12 @@ public class ValidateSignatureController {
@ModelAttribute SignatureValidationRequest request) throws IOException {
List<SignatureValidationResult> results = new ArrayList<>();
MultipartFile file = request.getFileInput();
MultipartFile certFile = request.getCertFile();
// Load custom certificate if provided
X509Certificate customCert = null;
if (request.getCertFile() != null && !request.getCertFile().isEmpty()) {
try (ByteArrayInputStream certStream =
new ByteArrayInputStream(request.getCertFile().getBytes())) {
if (certFile != null && !certFile.isEmpty()) {
try (ByteArrayInputStream certStream = new ByteArrayInputStream(certFile.getBytes())) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
customCert = (X509Certificate) cf.generateCertificate(certStream);
} catch (CertificateException e) {

View File

@ -2,6 +2,7 @@ package stirling.software.SPDF.controller.api.security;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyEditorSupport;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@ -24,6 +25,8 @@ import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -49,6 +52,18 @@ public class WatermarkController {
private final CustomPDFDocumentFactory pdfDocumentFactory;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(
MultipartFile.class,
new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(null);
}
});
}
@PostMapping(consumes = "multipart/form-data", value = "/add-watermark")
@Operation(
summary = "Add watermark to a PDF file",
@ -69,7 +84,7 @@ public class WatermarkController {
int widthSpacer = request.getWidthSpacer();
int heightSpacer = request.getHeightSpacer();
String customColor = request.getCustomColor();
boolean convertPdfToImage = request.isConvertPDFToImage();
boolean convertPdfToImage = Boolean.TRUE.equals(request.getConvertPDFToImage());
// Load the input PDF
PDDocument document = pdfDocumentFactory.load(pdfFile);

View File

@ -77,9 +77,8 @@ public class HomeWebController {
}
@GetMapping("/home-legacy")
public String homeLegacy(Model model) {
model.addAttribute("currentPage", "home-legacy");
return "home-legacy";
public String redirectHomeLegacy() {
return "redirect:/";
}
@GetMapping(value = "/robots.txt", produces = MediaType.TEXT_PLAIN_VALUE)

View File

@ -39,7 +39,6 @@ public class InputStreamTemplateResource implements ITemplateResource {
@Override
public boolean exists() {
// TODO Auto-generated method stub
return false;
return inputStream != null;
}
}

View File

@ -4,7 +4,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

View File

@ -11,6 +11,9 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class GeneralFile {
@Schema(description = "The input file")
@Schema(
description = "The input file",
requiredMode = Schema.RequiredMode.REQUIRED,
format = "binary")
private MultipartFile fileInput;
}

View File

@ -11,9 +11,12 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class HandleDataRequest {
@Schema(description = "The input files")
@Schema(description = "The input files", requiredMode = Schema.RequiredMode.REQUIRED)
private MultipartFile[] fileInput;
@Schema(description = "JSON String")
@Schema(
description = "JSON String",
defaultValue = "{}",
requiredMode = Schema.RequiredMode.REQUIRED)
private String json;
}

View File

@ -10,6 +10,9 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
public class ImageFile {
@Schema(description = "The input image file")
@Schema(
description = "The input image file",
requiredMode = Schema.RequiredMode.REQUIRED,
format = "binary")
private MultipartFile fileInput;
}

View File

@ -10,6 +10,6 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
public class MultiplePDFFiles {
@Schema(description = "The input PDF files", type = "array", format = "binary")
@Schema(description = "The input PDF files", requiredMode = Schema.RequiredMode.REQUIRED)
private MultipartFile[] fileInput;
}

View File

@ -11,6 +11,7 @@ public class PDFComparison extends PDFFile {
@Schema(
description = "The comparison type, accepts Greater, Equal, Less than",
allowableValues = {"Greater", "Equal", "Less"})
allowableValues = {"Greater", "Equal", "Less"},
requiredMode = Schema.RequiredMode.REQUIRED)
private String comparator;
}

View File

@ -8,6 +8,6 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class PDFComparisonAndCount extends PDFComparison {
@Schema(description = "Count")
private String pageCount;
@Schema(description = "Count", requiredMode = Schema.RequiredMode.REQUIRED, defaultValue = "0")
private int pageCount;
}

View File

@ -11,6 +11,8 @@ public class PDFExtractImagesRequest extends PDFWithImageFormatRequest {
@Schema(
description =
"Boolean to enable/disable the saving of duplicate images, true to enable duplicates")
private boolean allowDuplicates;
"Boolean to enable/disable the saving of duplicate images, true to enable"
+ " duplicates",
defaultValue = "false")
private Boolean allowDuplicates;
}

View File

@ -12,6 +12,10 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@EqualsAndHashCode
public class PDFFile {
@Schema(description = "The input PDF file", format = "binary")
@Schema(
description = "The input PDF file",
requiredMode = Schema.RequiredMode.REQUIRED,
contentMediaType = "application/pdf",
format = "binary")
private MultipartFile fileInput;
}

View File

@ -11,6 +11,8 @@ public class PDFWithImageFormatRequest extends PDFFile {
@Schema(
description = "The output image format e.g., 'png', 'jpeg', or 'gif'",
allowableValues = {"png", "jpeg", "gif"})
allowableValues = {"png", "jpeg", "gif"},
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "png")
private String format;
}

View File

@ -21,9 +21,9 @@ public class PDFWithPageNums extends PDFFile {
description =
"The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the"
+ " format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a"
+ " constant (e.g., '2n+1', '3n', '6n-5')\"",
+ " constant (e.g., '2n+1', '3n', '6n-5')",
defaultValue = "all",
requiredMode = RequiredMode.NOT_REQUIRED)
requiredMode = RequiredMode.REQUIRED)
private String pageNumbers;
@Hidden

View File

@ -11,7 +11,9 @@ public class PDFWithPageSize extends PDFFile {
@Schema(
description =
"The scale of pages in the output PDF. Acceptable values are A0-A6, LETTER, LEGAL, KEEP.",
"The scale of pages in the output PDF. Acceptable values are A0-A6, LETTER,"
+ " LEGAL, KEEP.",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "LETTER", "LEGAL", "KEEP"})
private String pageSize;
}

View File

@ -8,12 +8,22 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class SplitPdfByChaptersRequest extends PDFFile {
@Schema(description = "Whether to include Metadata or not", example = "true")
@Schema(
description = "Whether to include Metadata or not",
defaultValue = "true",
requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean includeMetadata;
@Schema(description = "Whether to allow duplicates or not", example = "true")
@Schema(
description = "Whether to allow duplicates or not",
defaultValue = "true",
requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean allowDuplicates;
@Schema(description = "Maximum bookmark level required", example = "2")
@Schema(
description = "Maximum bookmark level required",
minimum = "0",
defaultValue = "2",
requiredMode = Schema.RequiredMode.REQUIRED)
private Integer bookmarkLevel;
}

View File

@ -8,12 +8,23 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class SplitPdfBySectionsRequest extends PDFFile {
@Schema(description = "Number of horizontal divisions for each PDF page", example = "2")
@Schema(
description = "Number of horizontal divisions for each PDF page",
defaultValue = "0",
minimum = "0",
requiredMode = Schema.RequiredMode.REQUIRED)
private int horizontalDivisions;
@Schema(description = "Number of vertical divisions for each PDF page", example = "2")
@Schema(
description = "Number of vertical divisions for each PDF page",
defaultValue = "1",
minimum = "0",
requiredMode = Schema.RequiredMode.REQUIRED)
private int verticalDivisions;
@Schema(description = "Merge the split documents into a single PDF", example = "true")
private boolean merge;
@Schema(
description = "Merge the split documents into a single PDF",
defaultValue = "true",
requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean merge;
}

View File

@ -23,9 +23,9 @@ public class ConvertPDFToMarkdown {
summary = "Convert PDF to Markdown",
description =
"This endpoint converts a PDF file to Markdown format. Input:PDF Output:Markdown Type:SISO")
public ResponseEntity<byte[]> processPdfToMarkdown(@ModelAttribute PDFFile request)
public ResponseEntity<byte[]> processPdfToMarkdown(@ModelAttribute PDFFile file)
throws Exception {
MultipartFile inputFile = request.getFileInput();
MultipartFile inputFile = file.getFileInput();
PDFToFile pdfToFile = new PDFToFile();
return pdfToFile.processPdfToMarkdown(inputFile);
}

View File

@ -5,33 +5,38 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.model.api.PDFWithPageNums;
@Data
@EqualsAndHashCode(callSuper = true)
public class ConvertToImageRequest extends PDFFile {
public class ConvertToImageRequest extends PDFWithPageNums {
@Schema(
description = "The output image format",
allowableValues = {"png", "jpeg", "jpg", "gif", "webp"})
defaultValue = "png",
allowableValues = {"png", "jpeg", "jpg", "gif", "webp"},
requiredMode = Schema.RequiredMode.REQUIRED)
private String imageFormat;
@Schema(
description =
"Choose between a single image containing all pages or separate images for each page",
allowableValues = {"single", "multiple"})
"Choose between a single image containing all pages or separate images for each"
+ " page",
defaultValue = "multiple",
allowableValues = {"single", "multiple"},
requiredMode = Schema.RequiredMode.REQUIRED)
private String singleOrMultiple;
@Schema(
description =
"The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a constant (e.g., '2n+1', '3n', '6n-5')\"")
private String pageNumbers;
@Schema(
description = "The color type of the output image(s)",
allowableValues = {"color", "greyscale", "blackwhite"})
defaultValue = "color",
allowableValues = {"color", "greyscale", "blackwhite"},
requiredMode = Schema.RequiredMode.REQUIRED)
private String colorType;
@Schema(description = "The DPI (dots per inch) for the output image(s)")
private String dpi;
@Schema(
description = "The DPI (dots per inch) for the output image(s)",
defaultValue = "300",
requiredMode = Schema.RequiredMode.REQUIRED)
private Integer dpi;
}

View File

@ -11,21 +11,28 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class ConvertToPdfRequest {
@Schema(description = "The input images to be converted to a PDF file")
@Schema(
description = "The input images to be converted to a PDF file",
requiredMode = Schema.RequiredMode.REQUIRED)
private MultipartFile[] fileInput;
@Schema(
description = "Option to determine how the image will fit onto the page",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "fillPage",
allowableValues = {"fillPage", "fitDocumentToImage", "maintainAspectRatio"})
private String fitOption;
@Schema(
description = "The color type of the output image(s)",
defaultValue = "color",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"color", "greyscale", "blackwhite"})
private String colorType;
@Schema(
description = "Whether to automatically rotate the images to better fit the PDF page",
example = "true")
private boolean autoRotate;
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "false")
private Boolean autoRotate;
}

View File

@ -13,6 +13,7 @@ public class HTMLToPdfRequest extends PDFFile {
@Schema(
description = "Zoom level for displaying the website. Default is '1'.",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "1")
private float zoom;
}

View File

@ -13,6 +13,7 @@ public class PdfToBookRequest extends PDFFile {
@Schema(
description = "The output Ebook format",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {
"epub", "mobi", "azw3", "docx", "rtf", "txt", "html", "lit", "fb2", "pdb", "lrf"
})

View File

@ -13,6 +13,7 @@ public class PdfToPdfARequest extends PDFFile {
@Schema(
description = "The output PDF/A type",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"pdfa", "pdfa-1"})
private String outputFormat;
}

View File

@ -13,6 +13,7 @@ public class PdfToPresentationRequest extends PDFFile {
@Schema(
description = "The output Presentation format",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"ppt", "pptx", "odp"})
private String outputFormat;
}

View File

@ -13,6 +13,7 @@ public class PdfToTextOrRTFRequest extends PDFFile {
@Schema(
description = "The output Text or RTF format",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"rtf", "txt"})
private String outputFormat;
}

View File

@ -13,6 +13,7 @@ public class PdfToWordRequest extends PDFFile {
@Schema(
description = "The output Word document format",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"doc", "docx", "odt"})
private String outputFormat;
}

View File

@ -11,6 +11,9 @@ import stirling.software.SPDF.model.api.PDFWithPageNums;
@EqualsAndHashCode(callSuper = true)
public class ContainsTextRequest extends PDFWithPageNums {
@Schema(description = "The text to check for", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(
description = "The text to check for",
defaultValue = "text",
requiredMode = Schema.RequiredMode.REQUIRED)
private String text;
}

View File

@ -11,6 +11,9 @@ import stirling.software.SPDF.model.api.PDFComparison;
@EqualsAndHashCode(callSuper = true)
public class FileSizeRequest extends PDFComparison {
@Schema(description = "File Size", requiredMode = Schema.RequiredMode.REQUIRED)
private String fileSize;
@Schema(
description = "Size of the file in bytes",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "0")
private long fileSize;
}

View File

@ -11,6 +11,9 @@ import stirling.software.SPDF.model.api.PDFComparison;
@EqualsAndHashCode(callSuper = true)
public class PageRotationRequest extends PDFComparison {
@Schema(description = "Rotation in degrees", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(
description = "Rotation in degrees",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "0")
private int rotation;
}

View File

@ -11,6 +11,10 @@ import stirling.software.SPDF.model.api.PDFComparison;
@EqualsAndHashCode(callSuper = true)
public class PageSizeRequest extends PDFComparison {
@Schema(description = "Standard Page Size", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(
description = "Standard Page Size",
allowableValues = {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "LETTER", "LEGAL"},
defaultValue = "A4",
requiredMode = Schema.RequiredMode.REQUIRED)
private String standardPageSize;
}

View File

@ -13,10 +13,12 @@ public class MergeMultiplePagesRequest extends PDFFile {
@Schema(
description = "The number of pages to fit onto a single sheet in the output PDF.",
type = "integer",
type = "number",
defaultValue = "2",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"2", "3", "4", "9", "16"})
private int pagesPerSheet;
@Schema(description = "Boolean for if you wish to add border around the pages")
private boolean addBorder;
private Boolean addBorder;
}

View File

@ -20,12 +20,16 @@ public class MergePdfsRequest extends MultiplePDFFiles {
"byDateCreated",
"byPDFTitle"
},
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "orderProvided")
private String sortType = "orderProvided";
@Schema(
description =
"Flag indicating whether to remove certification signatures from the merged PDF. If true, all certification signatures will be removed from the final merged document.",
example = "true")
private boolean isRemoveCertSign;
"Flag indicating whether to remove certification signatures from the merged"
+ " PDF. If true, all certification signatures will be removed from the"
+ " final merged document.",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "true")
private Boolean removeCertSign;
}

View File

@ -15,21 +15,32 @@ public class OverlayPdfsRequest extends PDFFile {
@Schema(
description =
"An array of PDF files to be used as overlays on the base PDF. The order in these files is applied based on the selected mode.")
"An array of PDF files to be used as overlays on the base PDF. The order in"
+ " these files is applied based on the selected mode.",
requiredMode = Schema.RequiredMode.REQUIRED)
private MultipartFile[] overlayFiles;
@Schema(
description =
"The mode of overlaying: 'SequentialOverlay' for sequential application, 'InterleavedOverlay' for round-robin application, 'FixedRepeatOverlay' for fixed repetition based on provided counts",
"The mode of overlaying: 'SequentialOverlay' for sequential application,"
+ " 'InterleavedOverlay' for round-robin application, 'FixedRepeatOverlay'"
+ " for fixed repetition based on provided counts",
allowableValues = {"SequentialOverlay", "InterleavedOverlay", "FixedRepeatOverlay"},
requiredMode = Schema.RequiredMode.REQUIRED)
private String overlayMode;
@Schema(
description =
"An array of integers specifying the number of times each corresponding overlay file should be applied in the 'FixedRepeatOverlay' mode. This should match the length of the overlayFiles array.",
"An array of integers specifying the number of times each corresponding overlay"
+ " file should be applied in the 'FixedRepeatOverlay' mode. This should"
+ " match the length of the overlayFiles array.",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private int[] counts;
@Schema(description = "Overlay position 0 is Foregound, 1 is Background")
@Schema(
description = "Overlay position 0 is Foregound, 1 is Background",
allowableValues = {"0", "1"},
requiredMode = Schema.RequiredMode.REQUIRED,
type = "number")
private int overlayPosition;
}

View File

@ -14,6 +14,8 @@ public class RotatePDFRequest extends PDFFile {
@Schema(
description =
"The angle by which to rotate the PDF file. This should be a multiple of 90.",
example = "90")
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"0", "90", "180", "270"},
defaultValue = "90")
private Integer angle;
}

View File

@ -12,7 +12,11 @@ import stirling.software.SPDF.model.api.PDFWithPageSize;
public class ScalePagesRequest extends PDFWithPageSize {
@Schema(
minimum = "0",
defaultValue = "1",
requiredMode = Schema.RequiredMode.REQUIRED,
description =
"The scale of the content on the pages of the output PDF. Acceptable values are floats.")
"The scale of the content on the pages of the output PDF. Acceptable values are"
+ " floats.")
private float scaleFactor;
}

View File

@ -22,6 +22,7 @@ public class AddPageNumbersRequest extends PDFWithPageNums {
@Schema(
description = "Font size for page numbers",
minimum = "1",
defaultValue = "12",
requiredMode = RequiredMode.REQUIRED)
private float fontSize;
@ -33,15 +34,18 @@ public class AddPageNumbersRequest extends PDFWithPageNums {
@Schema(
description =
"Position: 1-9 representing positions on the page (1=top-left, 5=center, 9=bottom-right)",
minimum = "1",
maximum = "9",
"Position: 1-9 representing positions on the page (1=top-left, 2=top-center,"
+ " 3=top-right, 4=middle-left, 5=middle-center, 6=middle-right,"
+ " 7=bottom-left, 8=bottom-center, 9=bottom-right)",
allowableValues = {"1", "2", "3", "4", "5", "6", "7", "8", "9"},
defaultValue = "8",
requiredMode = RequiredMode.REQUIRED)
private int position;
@Schema(
description = "Starting number for page numbering",
minimum = "1",
defaultValue = "1",
requiredMode = RequiredMode.REQUIRED)
private int startingNumber;
@ -53,7 +57,8 @@ public class AddPageNumbersRequest extends PDFWithPageNums {
@Schema(
description =
"Custom text pattern. Available variables: {n}=current page number, {total}=total pages, {filename}=original filename",
"Custom text pattern. Available variables: {n}=current page number,"
+ " {total}=total pages, {filename}=original filename",
example = "Page {n} of {total}",
defaultValue = "{n}",
requiredMode = RequiredMode.NOT_REQUIRED)

View File

@ -19,51 +19,69 @@ public class AddStampRequest extends PDFWithPageNums {
requiredMode = Schema.RequiredMode.REQUIRED)
private String stampType;
@Schema(description = "The stamp text")
@Schema(description = "The stamp text", defaultValue = "Stirling Software")
private String stampText;
@Schema(description = "The stamp image")
private MultipartFile stampImage;
@Schema(
description = "The selected alphabet",
description = "The selected alphabet of the stamp text",
allowableValues = {"roman", "arabic", "japanese", "korean", "chinese"},
defaultValue = "roman")
private String alphabet = "roman";
@Schema(description = "The font size of the stamp text", example = "30")
private float fontSize = 30;
@Schema(
description = "The font size of the stamp text and image",
defaultValue = "30",
requiredMode = Schema.RequiredMode.REQUIRED)
private float fontSize;
@Schema(description = "The rotation of the stamp in degrees", example = "0")
private float rotation = 0;
@Schema(
description = "The rotation of the stamp in degrees",
defaultValue = "0",
requiredMode = Schema.RequiredMode.REQUIRED)
private float rotation;
@Schema(description = "The opacity of the stamp (0.0 - 1.0)", example = "0.5")
@Schema(
description = "The opacity of the stamp (0.0 - 1.0)",
defaultValue = "0.5",
requiredMode = Schema.RequiredMode.REQUIRED)
private float opacity;
@Schema(
description =
"Position for stamp placement based on a 1-9 grid (1: bottom-left, 2: bottom-center, ..., 9: top-right)",
example = "1")
"Position for stamp placement based on a 1-9 grid (1: bottom-left, 2: bottom-center,"
+ " 3: bottom-right, 4: middle-left, 5: middle-center, 6: middle-right,"
+ " 7: top-left, 8: top-center, 9: top-right)",
allowableValues = {"1", "2", "3", "4", "5", "6", "7", "8", "9"},
defaultValue = "5",
requiredMode = Schema.RequiredMode.REQUIRED)
private int position;
@Schema(
description =
"Override X coordinate for stamp placement. If set, it will override the position-based calculation. Negative value means no override.",
example = "-1")
private float overrideX = -1; // Default to -1 indicating no override
"Override X coordinate for stamp placement. If set, it will override the"
+ " position-based calculation. Negative value means no override.",
defaultValue = "-1",
requiredMode = Schema.RequiredMode.REQUIRED)
private float overrideX; // Default to -1 indicating no override
@Schema(
description =
"Override Y coordinate for stamp placement. If set, it will override the position-based calculation. Negative value means no override.",
example = "-1")
private float overrideY = -1; // Default to -1 indicating no override
"Override Y coordinate for stamp placement. If set, it will override the"
+ " position-based calculation. Negative value means no override.",
defaultValue = "-1",
requiredMode = Schema.RequiredMode.REQUIRED)
private float overrideY; // Default to -1 indicating no override
@Schema(
description = "Specifies the margin size for the stamp.",
allowableValues = {"small", "medium", "large", "x-large"},
defaultValue = "medium")
private String customMargin = "medium";
defaultValue = "medium",
requiredMode = Schema.RequiredMode.REQUIRED)
private String customMargin;
@Schema(description = "The color for stamp", defaultValue = "#d3d3d3")
private String customColor = "#d3d3d3";
@Schema(description = "The color of the stamp text", defaultValue = "#d3d3d3")
private String customColor;
}

View File

@ -16,5 +16,5 @@ public class AutoSplitPdfRequest extends PDFFile {
"Flag indicating if the duplex mode is active, where the page after the divider also gets removed.",
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
defaultValue = "false")
private boolean duplexMode;
private Boolean duplexMode;
}

View File

@ -16,5 +16,5 @@ public class ExtractHeaderRequest extends PDFFile {
"Flag indicating whether to use the first text as a fallback if no suitable title is found. Defaults to false.",
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
defaultValue = "false")
private boolean useFirstTextAsFallback;
private Boolean useFirstTextAsFallback;
}

View File

@ -12,36 +12,37 @@ import lombok.EqualsAndHashCode;
public class ExtractImageScansRequest {
@Schema(
description = "The input file containing image scans",
requiredMode = Schema.RequiredMode.REQUIRED)
requiredMode = Schema.RequiredMode.REQUIRED,
format = "binary")
private MultipartFile fileInput;
@Schema(
description = "The angle threshold for the image scan extraction",
defaultValue = "5",
example = "5")
private int angleThreshold = 5;
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "5")
private int angleThreshold;
@Schema(
description = "The tolerance for the image scan extraction",
defaultValue = "20",
example = "20")
private int tolerance = 20;
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "20")
private int tolerance;
@Schema(
description = "The minimum area for the image scan extraction",
defaultValue = "8000",
example = "8000")
private int minArea = 8000;
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "8000")
private int minArea;
@Schema(
description = "The minimum contour area for the image scan extraction",
defaultValue = "500",
example = "500")
private int minContourArea = 500;
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "500")
private int minContourArea;
@Schema(
description = "The border size for the image scan extraction",
defaultValue = "1",
example = "1")
private int borderSize = 1;
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "1")
private int borderSize;
}

View File

@ -13,6 +13,9 @@ public class FlattenRequest extends PDFFile {
@Schema(
description =
"True to flatten only the forms, false to flatten full PDF (Convert page to image)")
"True to flatten only the forms, false to flatten full PDF (Convert page to"
+ " image)",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "false")
private Boolean flattenOnlyForms;
}

View File

@ -13,38 +13,72 @@ import stirling.software.SPDF.model.api.PDFFile;
@EqualsAndHashCode(callSuper = true)
public class MetadataRequest extends PDFFile {
@Schema(description = "Delete all metadata if set to true")
private boolean deleteAll;
@Schema(
description = "Delete all metadata if set to true",
defaultValue = "false",
requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean deleteAll;
@Schema(description = "The author of the document")
@Schema(
description = "The author of the document",
defaultValue = "author",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String author;
@Schema(description = "The creation date of the document (format: yyyy/MM/dd HH:mm:ss)")
@Schema(
description = "The creation date of the document (format: yyyy/MM/dd HH:mm:ss)",
pattern = "yyyy/MM/dd HH:mm:ss",
defaultValue = "2023/10/01 12:00:00",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String creationDate;
@Schema(description = "The creator of the document")
@Schema(
description = "The creator of the document",
defaultValue = "creator",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String creator;
@Schema(description = "The keywords for the document")
@Schema(
description = "The keywords for the document",
defaultValue = "keywords",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String keywords;
@Schema(description = "The modification date of the document (format: yyyy/MM/dd HH:mm:ss)")
@Schema(
description = "The modification date of the document (format: yyyy/MM/dd HH:mm:ss)",
pattern = "yyyy/MM/dd HH:mm:ss",
defaultValue = "2023/10/01 12:00:00",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String modificationDate;
@Schema(description = "The producer of the document")
@Schema(
description = "The producer of the document",
defaultValue = "producer",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String producer;
@Schema(description = "The subject of the document")
@Schema(
description = "The subject of the document",
defaultValue = "subject",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String subject;
@Schema(description = "The title of the document")
@Schema(
description = "The title of the document",
defaultValue = "title",
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String title;
@Schema(description = "The trapped status of the document")
@Schema(
description = "The trapped status of the document",
defaultValue = "False",
allowableValues = {"True", "False", "Unknown"},
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String trapped;
@Schema(
description =
"Map list of key and value of custom parameters. Note these must start with customKey and customValue if they are non-standard")
"Map list of key and value of custom parameters. Note these must start with"
+ " customKey and customValue if they are non-standard")
private Map<String, String> allRequestParams;
}

View File

@ -13,30 +13,36 @@ public class OptimizePdfRequest extends PDFFile {
@Schema(
description =
"The level of optimization to apply to the PDF file. Higher values indicate greater compression but may reduce quality.",
"The level of optimization to apply to the PDF file. Higher values indicate"
+ " greater compression but may reduce quality.",
defaultValue = "5",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"1", "2", "3", "4", "5", "6", "7", "8", "9"})
private Integer optimizeLevel;
@Schema(description = "The expected output size, e.g. '100MB', '25KB', etc.")
@Schema(
description = "The expected output size, e.g. '100MB', '25KB', etc.",
defaultValue = "25KB",
requiredMode = Schema.RequiredMode.REQUIRED)
private String expectedOutputSize;
@Schema(
description = "Whether to linearize the PDF for faster web viewing. Default is false.",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "false")
private Boolean linearize = false;
@Schema(
description =
"Whether to normalize the PDF content for better compatibility. Default is false.",
"Whether to normalize the PDF content for better compatibility. Default is"
+ " false.",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "false")
private Boolean normalize = false;
@Schema(
description = "Whether to convert the PDF to grayscale. Default is false.",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "false")
private Boolean grayscale = false;
public Boolean getGrayscale() {
return grayscale;
}
}

View File

@ -13,21 +13,27 @@ import stirling.software.SPDF.model.api.PDFFile;
@EqualsAndHashCode(callSuper = true)
public class OverlayImageRequest extends PDFFile {
@Schema(description = "The image file to be overlaid onto the PDF.")
@Schema(
description = "The image file to be overlaid onto the PDF.",
requiredMode = Schema.RequiredMode.REQUIRED,
format = "binary")
private MultipartFile imageFile;
@Schema(
description = "The x-coordinate at which to place the top-left corner of the image.",
example = "0")
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "0")
private float x;
@Schema(
description = "The y-coordinate at which to place the top-left corner of the image.",
example = "0")
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "0")
private float y;
@Schema(
description = "Whether to overlay the image onto every page of the PDF.",
example = "false")
private boolean everyPage;
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "false")
private Boolean everyPage;
}

View File

@ -13,16 +13,21 @@ import stirling.software.SPDF.model.api.PDFFile;
@EqualsAndHashCode(callSuper = true)
public class ProcessPdfWithOcrRequest extends PDFFile {
@Schema(description = "List of languages to use in OCR processing")
@Schema(
description = "List of languages to use in OCR processing, e.g., 'eng', 'deu'",
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "[\"eng\"]")
private List<String> languages;
@Schema(
description = "Specify the OCR type, e.g., 'skip-text', 'force-ocr', or 'Normal'",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"skip-text", "force-ocr", "Normal"})
private String ocrType;
@Schema(
description = "Specify the OCR render type, either 'hocr' or 'sandwich'",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"hocr", "sandwich"},
defaultValue = "hocr")
private String ocrRenderType = "hocr";

Some files were not shown because too many files have changed in this diff Show More