Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Barcode4J and QRCode support #129

Merged
merged 2 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.quarkiverse.jasperreports.deployment;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedPackageBuildItem;
import io.quarkus.logging.Log;

/**
* Register Barcode4J and ZXING barcode libraries.
*/
public class BarcodeProcessor extends AbstractJandexProcessor {

@BuildStep
void indexTransitiveDependencies(BuildProducer<IndexDependencyBuildItem> index) {
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-barcode4j"));
index.produce(new IndexDependencyBuildItem("net.sf.barcode4j", "barcode4j"));
index.produce(new IndexDependencyBuildItem("com.google.zxing", "core"));
}

@BuildStep
void runtimeBarcodeInitializedClasses(BuildProducer<RuntimeInitializedPackageBuildItem> runtimeInitializedPackages) {
//@formatter:off
List<String> classes = new ArrayList<>(
Stream.of(org.krysalis.barcode4j.output.bitmap.BitmapEncoderRegistry.class.getName(),
net.sf.jasperreports.barcode4j.BarcodeUtils.class.getName()
).toList());
//@formatter:on
Log.debugf("Barcode4J Runtime: %s", classes);
classes.stream()
.map(RuntimeInitializedPackageBuildItem::new)
.forEach(runtimeInitializedPackages::produce);
}

@BuildStep
void registerBarcodeForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
CombinedIndexBuildItem combinedIndex) {
final List<String> classNames = new ArrayList<>();
classNames.add("javax.imageio.ImageIO");
classNames.add(org.krysalis.barcode4j.output.bitmap.ImageIOBitmapEncoder.class.getName());
classNames.addAll(collectClassesInPackage(combinedIndex,
net.sf.jasperreports.barcode4j.Barcode4JExtensionsRegistryFactory.class.getPackageName()));

Log.debugf("Barcode4J Reflection: %s", classNames);
// methods and fields
reflectiveClass.produce(
ReflectiveClassBuildItem.builder(classNames.toArray(new String[0])).methods().fields().serialization().build());
}

@BuildStep
void registerBarcodeResources(BuildProducer<NativeImageResourceBuildItem> nativeImageResourceProducer,
BuildProducer<NativeImageResourceBundleBuildItem> resourceBundleBuildItem) {
// Register individual resource files
nativeImageResourceProducer.produce(new NativeImageResourceBuildItem(
"org/krysalis/barcode4j/impl/fourstate/usps-4bc-bar-to-character-table.csv"));

// Register resource bundles
resourceBundleBuildItem
.produce(new NativeImageResourceBundleBuildItem("org.krysalis.barcode4j.impl.code128.EAN128AIs"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourcePatternsBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedPackageBuildItem;
import io.quarkus.logging.Log;
Expand All @@ -16,8 +17,15 @@ public class BatikProcessor extends AbstractJandexProcessor {

@BuildStep
void indexTransitiveDependencies(BuildProducer<IndexDependencyBuildItem> index) {
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-anim"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-awt-util"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-bridge"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-constants"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-css"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-dom"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-gvt"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-svg-dom"));
index.produce(new IndexDependencyBuildItem("org.apache.xmlgraphics", "batik-util"));
}

/**
Expand Down Expand Up @@ -56,12 +64,22 @@ void runtimeBatikInitializedClasses(BuildProducer<RuntimeInitializedPackageBuild
@BuildStep
void registerBatikForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
CombinedIndexBuildItem combinedIndex) {
final List<String> classNames = new ArrayList<>(
collectClassesInPackage(combinedIndex, org.apache.batik.gvt.font.AWTGVTFont.class.getPackageName()));
final List<String> classNames = new ArrayList<>();
classNames.addAll(collectImplementors(combinedIndex, org.apache.batik.css.parser.ExtendedParser.class.getName()));
classNames.addAll(collectClassesInPackage(combinedIndex, org.apache.batik.gvt.font.AWTGVTFont.class.getPackageName()));

Log.debugf("Batik Reflection: %s", classNames);
// methods and fields
reflectiveClass.produce(
ReflectiveClassBuildItem.builder(classNames.toArray(new String[0])).methods().fields().build());
}

@BuildStep
void registerBatikResources(BuildProducer<NativeImageResourcePatternsBuildItem> nativeImageResourcePatterns) {
// Register all message bundles
final NativeImageResourcePatternsBuildItem.Builder builder = NativeImageResourcePatternsBuildItem.builder();
builder.includeGlob("**/apache/batik/**/resources/**");
nativeImageResourcePatterns.produce(builder.build());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ void indexTransitiveDependencies(BuildProducer<IndexDependencyBuildItem> index)
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-data-adapters"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-excel-poi"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-jaxen"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-jdt"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-json"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-pdf"));
Expand Down Expand Up @@ -301,10 +300,10 @@ void registerResourceBuildItems(BuildProducer<NativeImageResourcePatternsBuildIt

// Register resource patterns for OOXML export and font icons
final NativeImageResourcePatternsBuildItem.Builder builder = NativeImageResourcePatternsBuildItem.builder();
builder.includeGlob("**/export/ooxml/docx/**");
builder.includeGlob("**/export/ooxml/pptx/**");
builder.includeGlob("**/export/ooxml/xlsx/**");
builder.includeGlob("**/sf/jasperreports/fonts/icons/**");
builder.includeGlob("net/sf/jasperreports/engine/export/ooxml/docx/**");
builder.includeGlob("net/sf/jasperreports/engine/export/ooxml/pptx/**");
builder.includeGlob("net/sf/jasperreports/engine/export/ooxml/xlsx/**");
builder.includeGlob("net/sf/jasperreports/fonts/icons/**");
nativeImageResourcePatterns.produce(builder.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class JaxenProcessor extends AbstractJandexProcessor {

@BuildStep
void indexTransitiveDependencies(BuildProducer<IndexDependencyBuildItem> index) {
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-jaxen"));
index.produce(new IndexDependencyBuildItem("jaxen", "jaxen"));
}

Expand Down
31 changes: 15 additions & 16 deletions docs/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ public byte[] text() throws JRException, SQLException {
}
----

== Read-Only Streaming Service

This extension offers an injectable JasperReports repository capable of managing all the resources required for a report, including referenced sub-reports. Just inject the `ReadOnlyStreamingService` repository and use it with the fill manager to generate the report.

[source,java]
----
@Inject
ReadOnlyStreamingService jasperService;

public JasperPrint fill() throws JRException {
Map<String, Object> params = new HashMap<>();
return JasperFillManager.getInstance(jasperService.getContext()).fillFromRepo("MyReport.jasper", params);
}
----


== Native Container

Expand Down Expand Up @@ -93,22 +108,6 @@ CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

CAUTION: Make sure `.dockerignore` does not exclude `.so` files!

== Read-Only Streaming Service

A JasperReports repository can handle loading all of the resources a report needs, including any referenced subreports. Simply inject the repository,
then use it with the fill manager to produce the report.

[source,java]
----
@Inject
ReadOnlyStreamingService repo;

public JasperPrint fill() throws JRException {
Map<String, Object> params = new HashMap<>();
return JasperFillManager.getInstance(repo.getContext()).fillFromRepo("MyReport.jasper", params);
}
----

[[extension-configuration-reference]]
== Extension Configuration Reference

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
<skipITs>true</skipITs>
<quarkus.native.enabled>true</quarkus.native.enabled>
<quarkus.native.additional-build-args>
--trace-object-instantiation=org.openxmlformats.schemas.wordprocessingml.x2006.main.STZoom$Enum
--trace-object-instantiation=net.sf.jasperreports.engine.component.DefaultComponentsBundle
</quarkus.native.additional-build-args>
</properties>
<build>
Expand Down
136 changes: 136 additions & 0 deletions integration-tests/src/main/jasperreports/Barcode4JReport.jrxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<jasperReport name="Barcode4JReport" language="java" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50" uuid="432a7055-07f0-43d2-8d4c-00337bfe4d0a">
<style name="Barcode" fontName="DejaVu Sans" fontSize="10.0"/>
<title height="742">
<element kind="line" uuid="f980135d-c40f-42a7-93cd-d9d82925d5e2" x="0" y="0" width="515" height="1"/>
<element kind="staticText" uuid="df70158b-7d84-4c11-ae3e-a7bd238bcf3f" x="0" y="10" width="515" height="30" fontSize="22.0" hTextAlign="Center">
<text><![CDATA[Barcode Sample]]></text>
</element>
<element kind="textField" uuid="50f14e7a-b548-4a5d-9395-a387ea2e7e81" x="0" y="50" width="515" height="20" fontSize="12.0" hTextAlign="Center">
<expression><![CDATA["This sample uses Barcode4J Version 2.0"]]></expression>
</element>
<element kind="textField" uuid="55317c38-260d-4fb5-8c73-693d6425c411" x="0" y="70" width="515" height="20" fontSize="12.0" linkType="Reference" hTextAlign="Center">
<expression><![CDATA["http://barcode4j.sourceforge.net/"]]></expression>
<hyperlinkReferenceExpression><![CDATA["http://barcode4j.sourceforge.net/"]]></hyperlinkReferenceExpression>
</element>
<element kind="staticText" uuid="e3c8aa4c-a571-4288-b6ab-9eca96752649" x="0" y="100" width="100" height="30" style="Barcode">
<text><![CDATA[Code 128]]></text>
</element>
<element kind="component" uuid="17dc8c86-0d9c-4542-b153-71844a13bfe5" x="130" y="100" width="200" height="30" style="Barcode">
<component kind="barcode4j:Code128" moduleWidth="1.0">
<codeExpression><![CDATA["0123456789"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="038aa527-7c7f-48b5-9547-7ba91470754c" x="0" y="135" width="100" height="30" style="Barcode">
<text><![CDATA[Codabar]]></text>
</element>
<element kind="component" uuid="a8dd7541-3d7d-44fc-9281-2bf0bd7ff556" x="130" y="135" width="200" height="30" style="Barcode">
<component kind="barcode4j:Codabar" moduleWidth="1.2" textPosition="none" wideFactor="4.0">
<codeExpression><![CDATA["01234567890"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="e819db15-0b87-47b8-8474-cbe17cc7a37a" x="0" y="170" width="100" height="40" style="Barcode">
<text><![CDATA[DataMatrix]]></text>
</element>
<element kind="component" uuid="3955570e-f418-4cf2-9a94-cbed633f8e68" x="130" y="170" width="70" height="40" style="Barcode">
<component kind="barcode4j:DataMatrix" moduleWidth="4.0">
<codeExpression><![CDATA["JasperReports"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="079dc326-5af1-4979-927c-3d9d75bfe21b" x="0" y="215" width="100" height="30" style="Barcode">
<text><![CDATA[EAN-128]]></text>
</element>
<element kind="component" uuid="d5a009ab-4cd5-401e-96c8-9ba64b1fc8e9" x="130" y="215" width="250" height="30" style="Barcode">
<component kind="barcode4j:EAN128" moduleWidth="1.4" checksumMode="check">
<codeExpression><![CDATA["0101234567890128"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="63b7698e-e4a1-4fff-9ea0-a9772dd5b2c4" x="0" y="250" width="100" height="30" style="Barcode">
<text><![CDATA[Code39]]></text>
</element>
<element kind="component" uuid="7fc9f508-28ba-4b6e-bf7d-2e5e39b98ed8" x="130" y="250" width="400" height="30" style="Barcode">
<component kind="barcode4j:Code39">
<codeExpression><![CDATA["0123456789"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="8ca7d2e2-c66f-4c25-ab3d-2fb15453b8b0" x="0" y="285" width="100" height="30" style="Barcode">
<text><![CDATA[USPS Intelligent Mail]]></text>
</element>
<element kind="component" uuid="8fdd4d61-26b7-4a0e-b569-18d70d929c10" x="130" y="285" width="400" height="30" style="Barcode">
<component kind="barcode4j:USPSIntelligentMail" ascenderHeight="8.0" trackHeight="10.0">
<codeExpression><![CDATA["00040123456200800001987654321"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="df0b440d-9a4f-49ea-aa1d-c860c2ad3911" x="0" y="320" width="100" height="30" style="Barcode">
<text><![CDATA[Royal Mail Customer]]></text>
</element>
<element kind="component" uuid="4d2d0a42-1318-4873-8572-3cca99ebde50" x="130" y="320" width="400" height="30" style="Barcode">
<component kind="barcode4j:RoyalMailCustomer" ascenderHeight="8.0" intercharGapWidth="2.5" trackHeight="10.0">
<codeExpression><![CDATA["0123456789"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="dc520315-36de-4535-9d40-2dc5b96e07bc" x="0" y="355" width="100" height="30" style="Barcode">
<text><![CDATA[Interleaved 2 of 5]]></text>
</element>
<element kind="component" uuid="26bab176-29df-4677-ba6a-e8df79eea8e1" x="130" y="355" width="400" height="30" style="Barcode">
<component kind="barcode4j:Interleaved2Of5">
<codeExpression><![CDATA["0123456789"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="ddcf57ba-86e5-4b2c-8293-89cc3c044890" x="0" y="390" width="100" height="30" style="Barcode">
<text><![CDATA[UPC-A]]></text>
</element>
<element kind="component" uuid="234c47ef-0149-43aa-9595-44eb81a2bd54" x="130" y="390" width="400" height="30" style="Barcode">
<component kind="barcode4j:UPCA">
<codeExpression><![CDATA["01234567890"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="1ee2c6c4-54d0-4bae-af20-03970939c63c" x="0" y="425" width="100" height="30" style="Barcode">
<text><![CDATA[UPC-E]]></text>
</element>
<element kind="component" uuid="51b4da4c-b93b-4757-9f6e-8757a6716ea1" x="130" y="425" width="400" height="30" style="Barcode">
<component kind="barcode4j:UPCE">
<codeExpression><![CDATA["01234133"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="2cb2f39b-a468-4d35-9047-2066f52aec84" x="0" y="460" width="100" height="30" style="Barcode">
<text><![CDATA[EAN-13]]></text>
</element>
<element kind="component" uuid="35e15c85-135e-4e4a-ada4-3caab948d304" x="130" y="460" width="400" height="30" style="Barcode">
<component kind="barcode4j:EAN13">
<codeExpression><![CDATA["012345678901"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="9399924d-03f6-4825-adfd-0a51cca77964" x="0" y="495" width="100" height="30" style="Barcode">
<text><![CDATA[EAN-8]]></text>
</element>
<element kind="component" uuid="00eb6f75-bdf7-408a-ba56-f76ecca2f8e6" x="130" y="495" width="400" height="30" style="Barcode">
<component kind="barcode4j:EAN8">
<codeExpression><![CDATA["01234565"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="6ffb2cc2-63fd-4754-b8c3-48828cca8ab1" x="0" y="530" width="100" height="20" style="Barcode">
<text><![CDATA[POSTNET]]></text>
</element>
<element kind="component" uuid="16fee5fe-1e0f-4f56-b240-64a2ff904744" x="130" y="530" width="400" height="20" style="Barcode">
<component kind="barcode4j:POSTNET" shortBarHeight="10.0" checksumMode="add">
<codeExpression><![CDATA["01234"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="c1127dd1-6cde-483c-8b1c-927b5fd285a3" x="0" y="555" width="100" height="30" style="Barcode">
<text><![CDATA[PDF417]]></text>
</element>
<element kind="component" uuid="f8257c9c-cc13-40f4-8c1e-b2dda037fb3d" x="130" y="555" width="400" height="30" style="Barcode">
<component kind="barcode4j:PDF417" moduleWidth="4.0">
<codeExpression><![CDATA["JasperReports"]]></codeExpression>
</component>
</element>
<element kind="staticText" uuid="c1127dd1-6cde-483c-8b1c-927b5fd285a3" x="0" y="600" width="100" height="80" style="Barcode">
<text><![CDATA[QRCode]]></text>
</element>
<element kind="component" uuid="f8257c9c-cc13-40f4-8c1e-b2dda037fb3d" mode="Opaque" x="130" y="600" width="400" height="80" forecolor="#0000FF" backcolor="#FFFF00" style="Barcode">
<component kind="barcode4j:QRCode" margin="2" errorCorrectionLevel="M">
<codeExpression><![CDATA["http://barcode4j.sourceforge.net/"]]></codeExpression>
</component>
</element>
</title>
</jasperReport>
Loading