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 9, 2024
1 parent 17fda27 commit 170e0f9
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 15 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,9 @@
package io.quarkiverse.jasperreports.deployment;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
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 @@ -12,6 +15,7 @@
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -38,6 +42,7 @@
import io.quarkus.logging.Log;
import net.sf.jasperreports.compilers.ReportExpressionEvaluationData;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JRReportCompileData;
import net.sf.jasperreports.engine.util.JRLoader;
Expand Down Expand Up @@ -379,19 +384,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 @@ -403,7 +408,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 @@ -413,12 +419,62 @@ 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.warnf("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<GeneratedClassBuildItem> compiledReportProducer, OutputTargetBuildItem outputTarget) {

Log.warnf("Found %s report(s) to compile? %s", reportFiles.size(), config.build().enable());
if (config.build().enable()) {
// make sure the destination path exists before we try to write files to it
Path outputFilePath = Path.of(outputTarget.getOutputDirectory().toString(), "classes",
config.build().destination().toString());
if (!outputFilePath.toFile().exists()) {
outputFilePath.toFile().mkdirs();
}

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

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

Log.warnf("Compiled size is %s", outputStream.size());

try (FileOutputStream fos = new FileOutputStream(outputFile)) {
outputStream.writeTo(fos);
}

compiledReportProducer
.produce(new GeneratedClassBuildItem(true, item.getFileName(), outputStream.toByteArray()));
} catch (JRException | IOException ex) {
Log.warnf("Error while compiling reports: %s", ex.getMessage());
Log.debug(ex);
}
}
} else {
Log.debug("Automatic report compilation disabled");
}
}

Expand Down Expand Up @@ -492,4 +548,4 @@ static Path findProjectRoot(Path outputDirectory) {
return outputDirectory;
}
}
}
}
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>
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ quarkus.log.file.format=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c] (%t) %s%e%n
quarkus.log.level=INFO
%prod.quarkus.log.category."net.sf.jasperreports".level=DEBUG
quarkus.log.category."net.sf.jasperreports.engine.util.JRClassLoader".level=DEBUG
quarkus.log.category."io.quarkiverse.jasperreports.deployment.JasperReportsProcessor".level=DEBUG
quarkus.log.category."io.quarkus.deployment.steps.ReflectiveHierarchyStep".level=ERROR
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 170e0f9

Please sign in to comment.