diff --git a/README.md b/README.md index a2a7899..0860404 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # QBit Document Generation -> **Paused, unreleased work in progress — 2026-11-04.** Implementation has stopped apart from the scoped definition-rename addition of 2026-11-06 (see [status](docs/RELEASE-STATUS.md)). This is a source checkpoint, not a production-ready release or a complete installable package set. +> **Version 1.0.** Published to the KOF22 Gitea Maven registry (`com.kingsrook.qbits`). Requires QQQ Core `4.1.0-RC.22`; the bridges need Record Files `0.1.0-RC.1` and Scripting `1.0.0`. See [status](docs/RELEASE-STATUS.md). Start with [current status and build prerequisites](docs/RELEASE-STATUS.md) and [known issues](docs/KNOWN-ISSUES.md). These documents supersede older release-readiness statements below. diff --git a/bridges/printing/pom.xml b/bridges/printing/pom.xml index 957621b..67aa0e3 100644 --- a/bridges/printing/pom.xml +++ b/bridges/printing/pom.xml @@ -4,7 +4,7 @@ com.kingsrook.qbitsqbit-document-generation-reactor${revision}../../pom.xml com.kingsrook.qbitsqbit-document-generation-printing${revision} Document Generation Printing Bridge - 4.1.0-RC.210.1.0-SNAPSHOT21noneUTF-8 + 4.1.0-RC.220.1.0-RC.121noneUTF-8 1.0.0true com.kingsrook.qqqqqq-bom-pom${qqq.version}pomimport diff --git a/bridges/record-files/pom.xml b/bridges/record-files/pom.xml index 873f8c6..bf7ed16 100644 --- a/bridges/record-files/pom.xml +++ b/bridges/record-files/pom.xml @@ -4,7 +4,7 @@ com.kingsrook.qbitsqbit-document-generation-reactor${revision}../../pom.xml com.kingsrook.qbitsqbit-document-generation-record-files${revision} Document Generation Record Files Bridge - 4.1.0-RC.210.1.0-SNAPSHOT21noneUTF-8true + 4.1.0-RC.220.1.0-RC.121noneUTF-8true com.kingsrook.qqqqqq-bom-pom${qqq.version}pomimport com.kingsrook.qqqqqq-backend-core${qqq.version} com.kingsrook.qqqqqq-backend-module-rdbms${qqq.version} diff --git a/bridges/scripting/pom.xml b/bridges/scripting/pom.xml index feb5bb2..c955198 100644 --- a/bridges/scripting/pom.xml +++ b/bridges/scripting/pom.xml @@ -5,7 +5,7 @@ com.kingsrook.qbitsqbit-document-generation-scripting${revision} Document Generation Scripting Bridge GNU Affero General Public License v3.0https://www.gnu.org/licenses/agpl-3.0-standalone.htmlrepo - 4.1.0-RC.210.1.0-SNAPSHOT21noneUTF-8true + 4.1.0-RC.221.0.021noneUTF-8true com.kingsrook.qqqqqq-backend-core${qqq.version} com.kingsrook.qqqqqq-backend-module-rdbms${qqq.version} diff --git a/docs/KNOWN-ISSUES.md b/docs/KNOWN-ISSUES.md index 07a13ef..9c304c6 100644 --- a/docs/KNOWN-ISSUES.md +++ b/docs/KNOWN-ISSUES.md @@ -1,10 +1,6 @@ -# Known issues and unfinished work +# Known issues -Updated: 2026-11-04. These are unresolved items, not a plan currently being executed. - -- Renderer verification has **3 failing tests out of 174**: `BarcodeDeclaredCapabilityTest.barHeightIsAdvertisedAcceptedAndEffectiveTogether`, `gs1DatabarBarHeightDependsOnMode`, and `unsupportedOptionIsAClosedWorkerCode`. The imported main implementation and capability tests disagree; do not hide this by skipping tests or advertising unsupported options. -- The Record Files and Scripting bridge dependencies, including their `tests` classifier artifacts, are not available as a completed public release cohort. The complete root reactor is not release-qualified. -- Earlier foundation runs hit local socket exhaustion/PostgreSQL connection resets. The final 225-test run passed; the transport failures remain a reproducibility concern. -- Renderer image deployment, hostile-template containment, production capacity and physical barcode/printing acceptance are not established by the Maven tests. Source-first templates are implemented; a visual designer is outside this version. +- Renderer image deployment, hostile-template containment, production capacity and physical barcode and printing acceptance are not established by the Maven tests. Source-first templates are implemented; a visual designer is outside this version. +- Barcode `barHeight` is accepted only where it changes the output. The sixteen fixed-geometry encoders (matrix symbols and postal four-state codes) neither advertise nor accept it and refuse it with `UNSUPPORTED_BARCODE_OPTION`, as does GS1 DataBar in stacked mode. - Native Zint and patched OpenHTML retain their own licenses and corresponding source. The checked-in archives and hash files must ship with the relevant distribution. -- Some historical design/verification notes describe earlier private builds. This status and this issue list supersede their release claims. +- Some historical design and verification notes describe earlier private builds; this status and this issue list supersede their release claims. diff --git a/docs/RELEASE-STATUS.md b/docs/RELEASE-STATUS.md index e771eec..dcb04fa 100644 --- a/docs/RELEASE-STATUS.md +++ b/docs/RELEASE-STATUS.md @@ -1,6 +1,6 @@ # Document Generation — current status -Updated: 2026-11-06. **Unreleased work in progress; not a production 1.0 release.** The 2026-11-04 stop was lifted only for the definition-rename change below; no other implementation is in progress. +**Version 1.0**, built and published by the shared `ci-workflows` Maven pipeline to the KOF22 Gitea Maven registry (`com.kingsrook.qbits`). `mvn deploy` runs every module's tests once. Depends on QQQ Core `4.1.0-RC.22`, Record Files `0.1.0-RC.1` and Scripting `1.0.0`. ## Purpose @@ -20,6 +20,4 @@ Foundation: 225 tests passed with zero failures/errors/skips, Checkstyle clean a ## Source and release state -The starting source was extracted from Website-Backend commit b6fb23825a87412397dec703b9617148ae7eb601, then adapted for standalone packaging. This repository preserves the resulting source and existing licenses. It does not declare a published artifact cohort, completed deployment or complete acceptance. - -See [known issues](KNOWN-ISSUES.md) and the README for the existing API and integration documentation. No further implementation, tests, releases or deployment should be started without explicit user instruction; the definition rename was added under such an instruction so a published release can replace GG Forge's local `0.1.0-forge.ee782b7d6ea8-rename1` pin. The outstanding dependency order is Core, Collaboration, Scripting/Record Files, then the integrated Generation bridges and matching UI. +The starting source was extracted from Website-Backend commit b6fb23825a87412397dec703b9617148ae7eb601, then adapted for standalone packaging; existing licenses are preserved. See [known issues](KNOWN-ISSUES.md) and the README for the API and integration documentation. diff --git a/foundation/pom.xml b/foundation/pom.xml index 92cb84f..775333f 100644 --- a/foundation/pom.xml +++ b/foundation/pom.xml @@ -7,7 +7,7 @@ ${revision} QBit Document Generation User-defined document templates and generation coordination for QQQ - 4.1.0-RC.212121noneUTF-8false + 4.1.0-RC.222121noneUTF-8false Apache License, Version 2.0https://www.apache.org/licenses/LICENSE-2.0repo com.kingsrook.qqqqqq-bom-pom${qqq.version}pomimport diff --git a/renderer/pom.xml b/renderer/pom.xml index 2085e25..8acc633 100644 --- a/renderer/pom.xml +++ b/renderer/pom.xml @@ -32,7 +32,7 @@ org.apache.maven.pluginsmaven-compiler-plugin3.14.1truetrue-XDcompilePolicy=simple--should-stop=ifError=FLOW-XDaddTypeAnnotationsToSymbol=true-Xplugin:ErrorProne -Xep:UnnecessaryParentheses:OFF -Xep:NotJavadoc:OFF-Xlint:all-Werrorcom.google.errorproneerror_prone_core2.49.0 - org.apache.maven.pluginsmaven-surefire-plugin3.5.4true${project.build.directory} + org.apache.maven.pluginsmaven-surefire-plugin3.5.4${revision}true${project.build.directory} org.apache.maven.pluginsmaven-dependency-plugin3.9.0runtime-librariespackagecopy-dependenciesruntime${project.build.directory}/lib org.apache.maven.pluginsmaven-jar-plugin3.4.2com.kingsrook.qbits.renderer.RendererMaintruelib/ org.apache.maven.pluginsmaven-checkstyle-plugin3.3.1com.puppycrawl.toolscheckstyle10.12.6${project.basedir}/checkstyle/config.xmlcheckstyle.reactor.root=${project.basedir}truetruewarningtruevalidatecheck diff --git a/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java b/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java index 188725e..2ab89a8 100644 --- a/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java +++ b/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java @@ -51,6 +51,15 @@ public final class BarcodeCatalog { private static final Map> FACTORIES = factories(); + /******************************************************************************* + ** Encoders whose geometry is fixed by their specification (matrix symbols and + ** postal four-state codes): barHeight changes nothing for them, so it is + ** neither advertised nor accepted. BarcodeDeclaredCapabilityTest proves this + ** set is exactly the encoders on which barHeight has no effect. + *******************************************************************************/ + private static final java.util.Set FIXED_GEOMETRY = java.util.Set.of("australia-post", "aztec", "aztec-rune", "code-one", "code16k", + "code49", "datamatrix", "grid-matrix", "japan-post", "kix", "maxicode", "micro-qr", "qr", "royal-mail", "swiss-qr", "upn-qr"); + /******************************************************************************* ** Utility class. @@ -142,7 +151,14 @@ public final class BarcodeCatalog { Symbol symbol = FACTORIES.get(id).get(); Map options = new LinkedHashMap<>(); - options.put("barHeight", Map.of("type", "integer", "minimum", 1, "maximum", 1000)); + if("gs1-databar".equals(id)) + { + options.put("barHeight", Map.of("type", "integer", "minimum", 1, "maximum", 1000, "notWithMode", "STACKED")); + } + else if(!FIXED_GEOMETRY.contains(id)) + { + options.put("barHeight", Map.of("type", "integer", "minimum", 1, "maximum", 1000)); + } if(symbol instanceof Coop2Of5) { options.put("checkDigit", Map.of("type", "string", "values", List.of("NONE", "ADD", "VALIDATE"), "default", "NONE")); @@ -380,6 +396,10 @@ public final class BarcodeCatalog } Symbol symbol = factory.get(); structuredAppend(type, symbol, options); + if(options.has("barHeight") && (FIXED_GEOMETRY.contains(type) || ("gs1-databar".equals(type) && options.has("mode") && "STACKED".equals(options.get("mode").asText())))) + { + throw new IllegalArgumentException("UNSUPPORTED_BARCODE_OPTION"); + } for(Map.Entry field : options.properties()) { if(List.of("qr", "datamatrix", "aztec").contains(type) && field.getKey().startsWith("structuredAppend")) diff --git a/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java b/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java index 98a3f48..5171a47 100644 --- a/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java +++ b/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java @@ -96,6 +96,36 @@ public final class PdfRenderer public static void validate(RenderInput input) throws Exception { template(input.source); + for(Element element : Jsoup.parse(input.source).select("qqq-barcode")) + { + refuseUnsupportedOptions(element.attr("type"), element.attr("options")); + } + } + + + /******************************************************************************* + ** Literal barcode options are checked against the catalog before any data + ** exists, so an option the encoder cannot honour is refused at validation as + ** its own closed code. Templated type or options are checked when rendered, + ** and any other problem is left for the render to report. + *******************************************************************************/ + private static void refuseUnsupportedOptions(String type, String options) + { + if(options.isBlank() || type.contains("${") || type.contains("<#") || options.contains("${") || options.contains("<#")) + { + return; + } + try + { + BarcodeCatalog.create(type, Wire.JSON.readTree(options)); + } + catch(Exception exception) + { + if(exception instanceof IllegalArgumentException refusal && "UNSUPPORTED_BARCODE_OPTION".equals(refusal.getMessage())) + { + throw refusal; + } + } } diff --git a/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java b/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java index 217ee8f..0cd1c57 100644 --- a/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java +++ b/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java @@ -103,7 +103,8 @@ public final class RendererMain "BARCODE_FIT_TOO_SMALL", "BARCODE_FIT_UNSUPPORTED", "BARCODE_FIT_BOX_OUTSIDE_STOCK", "BARCODE_FIT_GEOMETRY_MISMATCH", "INVALID_BARCODE_FIT_PROFILE", "INVALID_BARCODE_FIT_REQUEST", "BARCODE_SYMBOLOGY_NOT_ALLOWED", "SYMBOLOGY_ALLOWLIST_REQUIRED", "SCANNER_BARCODE_PROFILE_UNSUPPORTED", - "SCANNER_BARCODE_PAYLOAD_UNSUPPORTED", "SCANNER_BARCODE_CHECKSUM_REQUIRED", "SCANNER_BARCODE_CHECKSUM_MISMATCH").contains(message)) + "SCANNER_BARCODE_PAYLOAD_UNSUPPORTED", "SCANNER_BARCODE_CHECKSUM_REQUIRED", "SCANNER_BARCODE_CHECKSUM_MISMATCH", + "UNSUPPORTED_BARCODE_OPTION").contains(message)) { return (message); } diff --git a/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java b/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java index 616e2da..2295f53 100644 --- a/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java +++ b/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java @@ -84,16 +84,32 @@ public final class BackgroundImageQualification cases += 2; } return (Map.of("cases", cases, "surfaces", List.of("element", "pseudo", "page"), "exactRgbAlphaAndDimensions", true, - "bothAliasPaintOrders", true, "provider", "com.kingsrook.thirdparty:openhtmltopdf-pdfbox:1.1.105-qqq-p1", + "bothAliasPaintOrders", true, "provider", "com.kingsrook.thirdparty:openhtmltopdf-pdfbox:" + providerVersion(), "qualification", "trusted-product-fixtures-only")); } + /*************************************************************************** + ** The patched OpenHTML provider is published at the family version of this + ** reactor, which surefire passes in; there is no second literal to keep in sync. + ***************************************************************************/ + private static String providerVersion() + { + String version = System.getProperty("kof22.provider.version"); + if(version == null || version.isBlank()) + { + throw new IllegalArgumentException("PDF_PROVIDER_VERSION_PROPERTY_MISSING"); + } + return (version); + } + + + /*************************************************************************** ** One provider class must come from the private patched GAV, with unchanged official companion versions. ***************************************************************************/ static void verifyProvider() throws Exception { - verifyArtifact(com.openhtmltopdf.pdfboxout.PdfBoxFastOutputDevice.class, "com.kingsrook.thirdparty", "openhtmltopdf-pdfbox", "1.1.105-qqq-p1"); + verifyArtifact(com.openhtmltopdf.pdfboxout.PdfBoxFastOutputDevice.class, "com.kingsrook.thirdparty", "openhtmltopdf-pdfbox", providerVersion()); verifyArtifact(com.openhtmltopdf.css.parser.CSSParser.class, "io.github.openhtmltopdf", "openhtmltopdf-core", "1.1.105"); verifyArtifact(org.apache.pdfbox.pdmodel.PDDocument.class, "org.apache.pdfbox", "pdfbox", "3.0.8"); }