Skip to content

Commit

Permalink
Configuration for report file location
Browse files Browse the repository at this point in the history
* added runtime configuration to enable / disable building the reports
* added source (.jrxml) and destination (.jasper) paths for the reports
* ignore another NetBeans specific file for git
* reworked the file watching to only watch the report files in dev mode, but we need to collect the report files always so they can be compiled
* compile the found source files

Signed-off-by:Nathan Erwin <[email protected]>
  • Loading branch information
nderwin committed Oct 8, 2024
1 parent 45d5e88 commit 1857d89
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ bin/

# NetBeans
nb-configuration.xml
nbactions.xml

# Visual Studio Code
.vscode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.quarkiverse.jasperreports.deployment;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -9,6 +11,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

import org.jboss.jandex.ClassInfo;
Expand All @@ -19,6 +22,7 @@
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
Expand All @@ -28,12 +32,15 @@
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedPackageBuildItem;
import io.quarkus.deployment.pkg.builditem.UberJarMergedResourceBuildItem;
import io.quarkus.logging.Log;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.util.JRLoader;

class JasperReportsProcessor {

private static final String FEATURE = "jasperreports";
private static final String EXTENSIONS_FILE = "jasperreports_extension.properties";
private static final String DEFAULT_ROOT_PATH = "src";
private static final String DEFAULT_ROOT_PATH = "src/main/resources";

@BuildStep
FeatureBuildItem feature() {
Expand Down Expand Up @@ -142,20 +149,19 @@ void registerFonts(BuildProducer<NativeImageResourcePatternsBuildItem> nativeIma
nativeImageResourcePatterns.produce(builder.build());
}

@BuildStep(onlyIf = IsDevelopment.class)
ReportRootBuildItem defaultReportRoot() {

@BuildStep
ReportRootBuildItem defaultReportRoot(ReportConfig config) {
if (config.build().enable()) {
return new ReportRootBuildItem(config.build().source().toString());
}
return new ReportRootBuildItem(DEFAULT_ROOT_PATH);
}

@BuildStep(onlyIf = IsDevelopment.class)
void watchReportFiles(BuildProducer<HotDeploymentWatchedFileBuildItem> watchedPaths,
BuildProducer<ReportFileBuildItem> reportFiles,
List<ReportRootBuildItem> reportRoots) {

@BuildStep
void collectReportFiles(List<ReportRootBuildItem> reportRoots, BuildProducer<ReportFileBuildItem> reportFiles) {
final AtomicInteger count = new AtomicInteger(0);
for (ReportRootBuildItem reportRoot : reportRoots) {
Path startDir = Paths.get(reportRoot.getPath()); // Specify your starting directory
List<Path> foundFiles = new ArrayList<>();

try {
// reports - .jrxml
Expand All @@ -167,7 +173,8 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
// Check if the file has one of the desired extensions
for (String ext : ReportFileBuildItem.EXTENSIONS) {
if (file.toString().endsWith(ext)) {
foundFiles.add(file);
count.incrementAndGet();
reportFiles.produce(new ReportFileBuildItem(file));
break;
}
}
Expand All @@ -177,12 +184,46 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
} catch (IOException e) {
Log.error("Error looking for report files.", e);
}
}

// Print the found files
foundFiles.forEach((file) -> {
reportFiles.produce(new ReportFileBuildItem(file));
watchedPaths.produce(new HotDeploymentWatchedFileBuildItem(file.toString()));
});
Log.tracef("Collected %s report file(s)", count.get());
}

@BuildStep(onlyIf = IsDevelopment.class)
void watchReportFiles(BuildProducer<HotDeploymentWatchedFileBuildItem> watchedPaths,
List<ReportFileBuildItem> reportFiles) {

// Print the found files
reportFiles.forEach((file) -> {
Log.tracef("Watching report file %s", file);
watchedPaths.produce(new HotDeploymentWatchedFileBuildItem(file.getFileName()));
});
}

@BuildStep
void compileReports(ReportConfig config, List<ReportFileBuildItem> reportFiles,
BuildProducer<GeneratedResourceBuildItem> resourceProducer) {

if (config.build().enable()) {
// TODO - only compile if the report file has changed
for (ReportFileBuildItem item : reportFiles) {
String outputFile = item.getFileName().replace("." + ReportFileBuildItem.EXT_REPORT,
"." + ReportFileBuildItem.EXT_COMPILED);
Log.warnf("Compiling %s into %s", item.getFileName(), config.build().destination() + "/" + outputFile);

try (InputStream inputStream = JRLoader.getLocationInputStream(item.getFileName())) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
JasperCompileManager.compileReportToStream(inputStream, outputStream);

Log.warnf("Compiled size is %s", outputStream.size());
resourceProducer.produce(new GeneratedResourceBuildItem("META-INF/jasperreports/" + outputFile,
outputStream.toByteArray()));
} catch (JRException ex) {
} catch (IOException ex) {
}
}
} else {
Log.debug("Automatic report compilation disabled");
}
}

Expand All @@ -200,4 +241,4 @@ private List<String> collectClassesInPackage(CombinedIndexBuildItem combinedInde
}
return classes;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.quarkiverse.jasperreports.deployment;

import java.nio.file.Path;

import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;

@ConfigMapping(prefix = "quarkus.jasperreports")
@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
public interface ReportConfig {

/**
* Configuration options related to automatically building reports.
*/
BuildConfig build();

interface BuildConfig {

/**
* Enable building all report files.
*/
@WithDefault("true")
boolean enable();

/**
* The path where all source .jrxml files are located.
*/
@WithDefault("/src/main/jasperreports")
Path source();

/**
* The path where compiled reports are located.
*/
@WithDefault("jasperreports")
Path destination();

}

}
67 changes: 67 additions & 0 deletions integration-tests/src/main/jasperreports/CustomersReport.jrxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<jasperReport name="CustomersReport" language="java" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50" uuid="6386a198-a31e-4f65-936d-2bc9fe5ac907">
<style name="Sans_Normal" default="true" fontName="DejaVu Sans" fontSize="12.0" bold="false" italic="false" underline="false" strikeThrough="false"/>
<style name="Sans_Bold" fontName="DejaVu Sans" fontSize="12.0" bold="true" italic="false" underline="false" strikeThrough="false"/>
<style name="Sans_Italic" fontName="DejaVu Sans" fontSize="12.0" bold="false" italic="true" underline="false" strikeThrough="false"/>
<query language="xPath"><![CDATA[/Northwind/Customers]]></query>
<field name="CustomerID" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="CustomerID"/>
</field>
<field name="CompanyName" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="CompanyName"/>
</field>
<title height="50">
<element kind="line" uuid="9c2633d9-9bfe-433b-8f5f-533a8280c386" x="0" y="0" width="515" height="1"/>
<element kind="staticText" uuid="69cf7a16-df9e-4a92-8dee-005fa6f01193" x="0" y="10" width="515" height="30" fontSize="22.0" hTextAlign="Center" style="Sans_Normal">
<text><![CDATA[Customer Orders Report]]></text>
</element>
</title>
<pageHeader height="21">
<element kind="staticText" uuid="ee9cbaa3-142e-42ab-af98-2873869ded2d" mode="Opaque" x="0" y="5" width="515" height="15" forecolor="#FFFFFF" backcolor="#333333" style="Sans_Bold">
<text><![CDATA[Customer Order List]]></text>
</element>
</pageHeader>
<detail>
<band height="50">
<element kind="textField" uuid="880e92c9-d6cc-4ad4-bc60-7e45887b9fe1" x="5" y="5" width="100" height="15" printWhenDetailOverflows="true" style="Sans_Bold">
<expression><![CDATA[$F{CustomerID}]]></expression>
</element>
<element kind="staticText" uuid="e40dae0e-0859-4881-bbe2-290bfa88d7d7" x="404" y="5" width="100" height="15" printWhenDetailOverflows="true" printRepeatedValues="false" style="Sans_Bold">
<text><![CDATA[(continued)]]></text>
</element>
<element kind="line" uuid="2d5a60ee-3d8d-4f50-ba2a-72f82e76e38e" x="0" y="20" width="515" height="1" printWhenDetailOverflows="true"/>
<element kind="subreport" uuid="e7de82f1-2e1c-4459-bef3-307e57903e0b" x="5" y="25" width="507" height="20" backcolor="#FFCC99" printRepeatedValues="false" removeLineWhenBlank="true">
<expression><![CDATA["OrdersReport.jasper"]]></expression>
<parameter name="XML_DATA_DOCUMENT">
<expression><![CDATA[$P{XML_DATA_DOCUMENT}]]></expression>
</parameter>
<parameter name="XML_DATE_PATTERN">
<expression><![CDATA[$P{XML_DATE_PATTERN}]]></expression>
</parameter>
<parameter name="XML_NUMBER_PATTERN">
<expression><![CDATA[$P{XML_NUMBER_PATTERN}]]></expression>
</parameter>
<parameter name="XML_LOCALE">
<expression><![CDATA[$P{XML_LOCALE}]]></expression>
</parameter>
<parameter name="XML_TIME_ZONE">
<expression><![CDATA[$P{XML_TIME_ZONE}]]></expression>
</parameter>
<parameter name="CustomerID">
<expression><![CDATA[$F{CustomerID}]]></expression>
</parameter>
</element>
<element kind="textField" uuid="ded07e37-4c41-4617-9f13-8a819cc1e745" x="109" y="5" width="291" height="15" printWhenDetailOverflows="true" style="Sans_Bold">
<expression><![CDATA[$F{CompanyName}]]></expression>
</element>
</band>
</detail>
<pageFooter height="40">
<element kind="line" uuid="33a41154-ab20-4fbc-8f20-b47eb00b7c12" x="0" y="10" width="515" height="1"/>
<element kind="textField" uuid="e6339776-ad98-448c-9ede-58a76a109cc0" x="200" y="20" width="80" height="15" hTextAlign="Right">
<expression><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></expression>
</element>
<element kind="textField" uuid="36404df1-6aa0-467f-915b-9b0166073249" x="280" y="20" width="75" height="15" evaluationTime="Report">
<expression><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></expression>
</element>
</pageFooter>
</jasperReport>
67 changes: 67 additions & 0 deletions integration-tests/src/main/jasperreports/OrdersReport.jrxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<jasperReport name="OrdersReport" language="java" pageWidth="500" pageHeight="842" columnWidth="500" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="10ec9c66-f0a7-416e-8fb0-d1fd1cea41fc">
<style name="Sans_Normal" default="true" fontName="DejaVu Sans" fontSize="8.0" bold="false" italic="false" underline="false" strikeThrough="false"/>
<style name="Sans_Bold" fontName="DejaVu Sans" fontSize="8.0" bold="true" italic="false" underline="false" strikeThrough="false"/>
<style name="Sans_Italic" fontName="DejaVu Sans" fontSize="8.0" bold="false" italic="true" underline="false" strikeThrough="false"/>
<parameter name="CustomerID" class="java.lang.String"/>
<query language="xPath"><![CDATA[/Northwind/Orders[CustomerID='$P{CustomerID}']]]></query>
<field name="Id" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="OrderID"/>
</field>
<field name="OrderDate" class="java.util.Date">
<property name="net.sf.jasperreports.xpath.field.expression" value="OrderDate"/>
</field>
<field name="ShipCity" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="ShipCity"/>
</field>
<field name="Freight" class="java.lang.Float">
<property name="net.sf.jasperreports.xpath.field.expression" value="Freight"/>
</field>
<variable name="TotalFreight" calculation="Sum" class="java.lang.Float">
<expression><![CDATA[$F{Freight}]]></expression>
</variable>
<pageHeader height="14">
<element kind="frame" uuid="4a580d60-8a5e-4e55-8a52-b88cde59c162" mode="Opaque" x="0" y="2" width="356" height="10" forecolor="#CCFFFF" backcolor="#CCFFFF">
<element kind="staticText" uuid="d2ab3078-a562-4679-85d2-8345668f8fff" mode="Opaque" x="0" y="0" width="48" height="10" backcolor="#CCFFFF" hTextAlign="Right" style="Sans_Bold">
<text><![CDATA[ID]]></text>
</element>
<element kind="staticText" uuid="c8c56ac9-453f-4904-8cf1-a4efc6a393ff" mode="Opaque" x="54" y="0" width="87" height="10" backcolor="#CCFFFF" hTextAlign="Center" style="Sans_Bold">
<text><![CDATA[Order Date]]></text>
</element>
<element kind="staticText" uuid="4c98dac9-95fc-4da9-8b96-09f556997c91" mode="Opaque" x="146" y="0" width="108" height="10" backcolor="#CCFFFF" style="Sans_Bold">
<text><![CDATA[Ship City]]></text>
</element>
<element kind="staticText" uuid="b62f2bab-65f3-4300-a4a5-2422a89122c9" mode="Opaque" x="259" y="0" width="92" height="10" backcolor="#CCFFFF" hTextAlign="Right" style="Sans_Bold">
<text><![CDATA[Freight]]></text>
</element>
</element>
</pageHeader>
<detail>
<band height="14">
<element kind="textField" uuid="42985753-7ba1-4b43-a8a2-13a9e3894651" x="0" y="2" width="51" height="10" hTextAlign="Right">
<expression><![CDATA[$F{Id}]]></expression>
</element>
<element kind="textField" uuid="1886b1ce-67ff-4457-89de-7baeae1446d0" positionType="Float" x="54" y="2" width="87" height="10" textAdjust="StretchHeight" pattern="yyyy, MMM dd" hTextAlign="Center">
<expression><![CDATA[$F{OrderDate}]]></expression>
</element>
<element kind="textField" uuid="c8ea91e7-4bc6-4059-99e6-ad296e4dcf26" positionType="Float" x="146" y="2" width="108" height="10" textAdjust="StretchHeight">
<expression><![CDATA[$F{ShipCity}]]></expression>
</element>
<element kind="textField" uuid="fe05b06c-95b5-4847-8567-130b3785c8dd" positionType="Float" x="259" y="2" width="92" height="10" textAdjust="StretchHeight" pattern="¤ #,##0.00" hTextAlign="Right">
<expression><![CDATA[$F{Freight}]]></expression>
</element>
</band>
</detail>
<summary height="14">
<element kind="frame" uuid="88ac99e2-eb7a-4705-be18-6e8c724c02b1" mode="Opaque" x="0" y="2" width="356" height="10" forecolor="#33CCCC" backcolor="#33CCCC">
<element kind="staticText" uuid="256d6372-5c9b-4260-af95-3ee29b2f5740" mode="Opaque" x="160" y="0" width="67" height="10" backcolor="#33CCCC" hTextAlign="Right" style="Sans_Bold">
<text><![CDATA[Total :]]></text>
</element>
<element kind="textField" uuid="de9ec45f-b4c7-48b4-bc2c-5f1f782c67a5" mode="Opaque" x="259" y="0" width="92" height="10" backcolor="#33CCCC" hTextAlign="Right" style="Sans_Bold">
<expression><![CDATA[$V{TotalFreight}]]></expression>
</element>
<element kind="textField" uuid="623fe099-1d25-4731-9eab-6e4138357bbc" mode="Opaque" x="227" y="0" width="27" height="10" backcolor="#33CCCC" hTextAlign="Right" style="Sans_Bold">
<expression><![CDATA[$V{REPORT_COUNT}]]></expression>
</element>
</element>
</summary>
</jasperReport>
2 changes: 2 additions & 0 deletions runtime/src/main/resources/META-INF/quarkus-extension.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ metadata:
- "excel"
categories:
- "miscellaneous"
config:
- "quarkus.jasperreports."
status: "preview"
guide: "https://docs.quarkiverse.io/quarkus-jasperreports/dev/index.html"
icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-jasperreports/main/docs/modules/ROOT/assets/images/jasperreports.svg"

0 comments on commit 1857d89

Please sign in to comment.