Skip to content

Commit

Permalink
Fix #115: Record build config and produce bean
Browse files Browse the repository at this point in the history
  • Loading branch information
melloware committed Oct 13, 2024
1 parent fe6a575 commit 6d5a5a5
Show file tree
Hide file tree
Showing 8 changed files with 353 additions and 159 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.quarkiverse.jasperreports.deployment.item;

import static io.quarkiverse.jasperreports.Constants.EXT_COMPILED;
import static io.quarkiverse.jasperreports.Constants.EXT_DATA_ADAPTER;
import static io.quarkiverse.jasperreports.Constants.EXT_REPORT;
import static io.quarkiverse.jasperreports.Constants.EXT_STYLE;
import static io.quarkiverse.jasperreports.config.Constants.EXT_COMPILED;
import static io.quarkiverse.jasperreports.config.Constants.EXT_DATA_ADAPTER;
import static io.quarkiverse.jasperreports.config.Constants.EXT_REPORT;
import static io.quarkiverse.jasperreports.config.Constants.EXT_STYLE;

import java.nio.file.Path;
import java.util.List;
Expand Down Expand Up @@ -50,4 +50,4 @@ public String getType() {
};
}

}
}
16 changes: 8 additions & 8 deletions runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@
<groupId>org.jboss.logging</groupId>
<artifactId>commons-logging-jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
</dependency>

<!-- JasperReports -->
<dependency>
Expand Down Expand Up @@ -107,14 +115,6 @@
<artifactId>fop</artifactId>
<version>2.10</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.quarkiverse.jasperreports;

import java.nio.file.Path;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.inject.Produces;

import io.quarkiverse.jasperreports.repository.ReadOnlyStreamingService;

/**
* A bean producer for JasperReports-related services.
* This class is responsible for initializing and producing the ReadOnlyStreamingService.
*/
@ApplicationScoped
public class JasperReportsBeanProducer {

private volatile Path destinationPath;

/**
* Initializes the bean producer with the destination path for JasperReports files.
*
* @param destinationPath The path where compiled JasperReports files are located.
*/
void initialize(Path destinationPath) {
this.destinationPath = destinationPath;
}

/**
* Produces a ReadOnlyStreamingService instance.
*
* @return A new ReadOnlyStreamingService initialized with the destination path.
*/
@Dependent
@Produces
public ReadOnlyStreamingService readOnlyStreamingService() {
return new ReadOnlyStreamingService(this.destinationPath);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkiverse.jasperreports;

import io.quarkiverse.jasperreports.config.ReportBuildTimeConfig;
import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.runtime.annotations.Recorder;

/**
* Recorder for JasperReports initialization.
* This class is responsible for initializing the JasperReportsBeanProducer at runtime.
*/
@Recorder
public class JasperReportsRecorder {

/**
* Initializes the JasperReportsBeanProducer with the configured destination path.
*
* @param container The BeanContainer used to retrieve the JasperReportsBeanProducer instance.
* @param config The ReportBuildTimeConfig containing the build configuration.
*/
public void initProducer(BeanContainer container, ReportBuildTimeConfig config) {
JasperReportsBeanProducer producer = container.beanInstance(JasperReportsBeanProducer.class);
producer.initialize(config.build().destination());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkiverse.jasperreports;
package io.quarkiverse.jasperreports.config;

public interface Constants {

Expand All @@ -14,4 +14,4 @@ public interface Constants {

static final String DEFAULT_DEST_PATH = "jasperreports";

}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkiverse.jasperreports.deployment.config;
package io.quarkiverse.jasperreports.config;

import java.nio.file.Path;

Expand All @@ -8,8 +8,8 @@
import io.smallrye.config.WithDefault;

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

String DEFAULT_SOURCE_PATH = "src/main/jasperreports";
String DEFAULT_DEST_PATH = "jasperreports";
Expand Down Expand Up @@ -40,4 +40,4 @@ interface BuildConfig {
Path destination();
}

}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
package io.quarkiverse.jasperreports.repository;

import static io.quarkiverse.jasperreports.Constants.EXT_COMPILED;
import static io.quarkiverse.jasperreports.Constants.EXT_DATA_ADAPTER;
import static io.quarkiverse.jasperreports.Constants.EXT_STYLE;
import static io.quarkiverse.jasperreports.config.Constants.EXT_COMPILED;
import static io.quarkiverse.jasperreports.config.Constants.EXT_DATA_ADAPTER;
import static io.quarkiverse.jasperreports.config.Constants.EXT_STYLE;

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Optional;

import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.Dependent;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.logging.Logger;

import io.quarkiverse.jasperreports.Constants;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.SimpleJasperReportsContext;
Expand All @@ -31,73 +25,116 @@
import net.sf.jasperreports.repo.SimpleRepositoryContext;
import net.sf.jasperreports.repo.StreamRepositoryService;

@Dependent
/**
* A read-only implementation of StreamRepositoryService for JasperReports.
* This service provides access to compiled reports, styles, and data adapters
* from a specified destination path.
*/
public class ReadOnlyStreamingService implements StreamRepositoryService {

private static final Logger LOG = Logger.getLogger(ReadOnlyStreamingService.class);

private final JasperReportsContext context = new SimpleJasperReportsContext();

// TODO - why is it not picking up the default value from ReportConfig???
@ConfigProperty(name = "quarkus.jasperreports.build.destination", defaultValue = Constants.DEFAULT_DEST_PATH)
Optional<Path> reportPathConfig;

@PostConstruct
public void onInit() {
((SimpleJasperReportsContext) context).setExtensions(RepositoryService.class, Collections.singletonList(this));
((SimpleJasperReportsContext) context).setExtensions(PersistenceServiceFactory.class,
private final Path destinationPath;

/**
* Constructs a new ReadOnlyStreamingService with the specified destination path.
*
* @param destinationPath The path where compiled reports and styles are located.
*/
public ReadOnlyStreamingService(Path destinationPath) {
this.destinationPath = destinationPath;
SimpleJasperReportsContext simpleContext = ((SimpleJasperReportsContext) context);
simpleContext.setExtensions(RepositoryService.class, Collections.singletonList(this));
simpleContext.setExtensions(PersistenceServiceFactory.class,
Collections.singletonList(FileRepositoryPersistenceServiceFactory.getInstance()));
}

/**
* Returns the JasperReportsContext associated with this service.
*
* @return The JasperReportsContext instance.
*/
public JasperReportsContext getContext() {
return context;
}

/**
* Retrieves an InputStream for the specified URI.
* This method handles compiled reports, styles, and data adapters.
*
* @param uri The URI of the resource to retrieve.
* @return An InputStream for the requested resource, or null if not found.
*/
@Override
public InputStream getInputStream(String uri) {
InputStream is = null;
String logType = null;
String filePath = uri;

if (uri.endsWith(EXT_COMPILED) || uri.endsWith(EXT_STYLE)) {
final Path reportPath = Path.of(reportPathConfig.get().toString(), uri);
final String reportFile = reportPath.toString();

try {
LOG.debugf("Loading %s file %s", (uri.endsWith(EXT_COMPILED) ? "report" : "style"), reportFile);

return JRLoader.getLocationInputStream(reportFile);
} catch (JRException ex) {
LOG.warnf("Failed to load %s - %s", (uri.endsWith(EXT_COMPILED) ? "report" : "style"), ex.getMessage());
LOG.debug(ex);
}
logType = uri.endsWith(EXT_COMPILED) ? "report" : "style";
filePath = Path.of(this.destinationPath.toString(), uri).toString();
} else if (uri.endsWith(EXT_DATA_ADAPTER)) {
try {
LOG.debugf("Loading data adapter file %s", uri);
logType = "data adapter";
}

return JRLoader.getLocationInputStream(uri);
if (logType != null) {
try {
LOG.debugf("Loading %s file %s", logType, filePath);
return JRLoader.getLocationInputStream(filePath);
} catch (JRException ex) {
LOG.warnf("Failed to load data adapter - %s", ex.getMessage());
LOG.warnf("Failed to load %s - %s", logType, ex.getMessage());
LOG.debug(ex);
}
}

return is;
return null;
}

/**
* This method is not supported in this read-only implementation.
*
* @param uri The URI of the resource.
* @return This method always throws an IllegalStateException.
* @throws IllegalStateException Always thrown as this repository is read-only.
*/
@Override
public OutputStream getOutputStream(String uri) {
throw new IllegalStateException("This repository is read only");
}

/**
* This method is not supported in this implementation.
*
* @param uri The URI of the resource.
* @return This method always throws an IllegalStateException.
* @throws IllegalStateException Always thrown as this method is not supported.
*/
@Override
public Resource getResource(String uri) {
throw new IllegalStateException("Can only return an InputStream");
}

/**
* This method is not supported in this read-only implementation.
*
* @param uri The URI of the resource.
* @param resource The resource to save.
* @throws IllegalStateException Always thrown as this repository is read-only.
*/
@Override
public void saveResource(String uri, Resource resource) {
throw new IllegalStateException("This repository is read only");
}

/**
* Retrieves a resource of the specified type for the given URI.
*
* @param <T> The type of resource to retrieve.
* @param uri The URI of the resource.
* @param resourceType The class of the resource type.
* @return The requested resource, or null if not found or if no appropriate PersistenceService is available.
*/
@Override
@SuppressWarnings("unchecked")
public <T extends Resource> T getResource(String uri, Class<T> resourceType) {
Expand All @@ -112,4 +149,4 @@ public <T extends Resource> T getResource(String uri, Class<T> resourceType) {
return null;
}

}
}

0 comments on commit 6d5a5a5

Please sign in to comment.