Skip to content

Commit

Permalink
Switch Xalan for Jaxen (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
melloware authored Oct 10, 2024
1 parent a23df50 commit c0263c7
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 375 deletions.
4 changes: 0 additions & 4 deletions deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-awt-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jaxp-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.poi</groupId>
<artifactId>quarkus-poi-deployment</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.quarkiverse.jasperreports.deployment;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;

import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.logging.Log;

abstract class AbstractJandexProcessor {

protected List<String> collectClassesInPackage(CombinedIndexBuildItem combinedIndex, String packageName) {
final List<String> classes = new ArrayList<>();
final List<DotName> packages = new ArrayList<>(combinedIndex.getIndex().getSubpackages(packageName));
packages.add(DotName.createSimple(packageName));
for (DotName aPackage : packages) {
final List<String> packageClasses = combinedIndex.getIndex()
.getClassesInPackage(aPackage)
.stream()
.map(ClassInfo::toString)
.toList();
classes.addAll(packageClasses);
}
Log.debugf("Package Classes: %s", classes);
return classes;
}

protected List<String> collectInterfacesInPackage(CombinedIndexBuildItem combinedIndex, String packageName) {
final List<String> classes = new ArrayList<>();
final List<DotName> packages = new ArrayList<>(combinedIndex.getIndex().getSubpackages(packageName));
packages.add(DotName.createSimple(packageName));
for (DotName aPackage : packages) {
final List<String> packageClasses = combinedIndex.getIndex()
.getClassesInPackage(aPackage)
.stream()
.filter(ClassInfo::isInterface) // Filter only interfaces
.map(ClassInfo::toString)
.toList();
classes.addAll(packageClasses);
}
Log.debugf("Package Interfaces: %s", classes);
return classes;
}

protected List<String> collectSubclasses(CombinedIndexBuildItem combinedIndex, String className) {
List<String> classes = combinedIndex.getIndex()
.getAllKnownSubclasses(DotName.createSimple(className))
.stream()
.map(ClassInfo::toString)
.collect(Collectors.toList());
classes.add(className);
Log.debugf("Subclasses: %s", classes);
return classes;
}

protected List<String> collectImplementors(CombinedIndexBuildItem combinedIndex, String className) {
Set<String> classes = combinedIndex.getIndex()
.getAllKnownImplementors(DotName.createSimple(className))
.stream()
.map(ClassInfo::toString)
.collect(Collectors.toCollection(HashSet::new));
classes.add(className);
Set<String> subclasses = new HashSet<>();
for (String implementationClass : classes) {
subclasses.addAll(collectSubclasses(combinedIndex, implementationClass));
}
classes.addAll(subclasses);
Log.debugf("Implementors: %s", classes);
return new ArrayList<>(classes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
import java.util.List;
import java.util.stream.Stream;

import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;

import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
Expand All @@ -15,7 +12,7 @@
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedPackageBuildItem;
import io.quarkus.logging.Log;

public class BatikProcessor {
public class BatikProcessor extends AbstractJandexProcessor {

@BuildStep
void indexTransitiveDependencies(BuildProducer<IndexDependencyBuildItem> index) {
Expand All @@ -29,7 +26,7 @@ void indexTransitiveDependencies(BuildProducer<IndexDependencyBuildItem> index)
* @param runtimeInitializedPackages Producer for runtime initialized packages
*/
@BuildStep
void runtimeInitializedClasses(BuildProducer<RuntimeInitializedPackageBuildItem> runtimeInitializedPackages) {
void runtimeBatikInitializedClasses(BuildProducer<RuntimeInitializedPackageBuildItem> runtimeInitializedPackages) {
//@formatter:off
List<String> classes = new ArrayList<>(Stream.of("javax.swing",
"javax.swing.plaf.metal",
Expand All @@ -50,37 +47,21 @@ void runtimeInitializedClasses(BuildProducer<RuntimeInitializedPackageBuildItem>
org.apache.batik.script.jpython.JPythonInterpreter.class.getPackageName(),
org.apache.batik.script.InterpreterPool.class.getName()).toList());
//@formatter:on
Log.debugf("Runtime: %s", classes);
Log.debugf("Batik Runtime: %s", classes);
classes.stream()
.map(RuntimeInitializedPackageBuildItem::new)
.forEach(runtimeInitializedPackages::produce);
}

@BuildStep
void registerForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
void registerBatikForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
CombinedIndexBuildItem combinedIndex) {
final List<String> classNames = new ArrayList<>(
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());
}

private List<String> collectClassesInPackage(CombinedIndexBuildItem combinedIndex, String packageName) {
final List<String> classes = new ArrayList<>();
final List<DotName> packages = new ArrayList<>(combinedIndex.getIndex().getSubpackages(packageName));
packages.add(DotName.createSimple(packageName));
for (DotName aPackage : packages) {
final List<String> packageClasses = combinedIndex.getIndex()
.getClassesInPackage(aPackage)
.stream()
.map(ClassInfo::toString)
.toList();
classes.addAll(packageClasses);
}
Log.tracef("Package: %s", classes);
return classes;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;

import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
Expand Down Expand Up @@ -48,7 +45,7 @@
* including feature registration, resource merging, dependency indexing,
* and reflection configuration.
*/
class JasperReportsProcessor {
class JasperReportsProcessor extends AbstractJandexProcessor {

private static final String FEATURE = "jasperreports";
private static final String EXTENSIONS_FILE = "jasperreports_extension.properties";
Expand Down Expand Up @@ -87,9 +84,9 @@ 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-pdf"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-xalan"));
}

/**
Expand Down Expand Up @@ -194,7 +191,7 @@ void registerForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveCla

//@formatter:on
final TreeSet<String> uniqueClasses = new TreeSet<>(classNames);
Log.debugf("Reflection: %s", uniqueClasses);
Log.debugf("Jasper Reflection: %s", uniqueClasses);

reflectiveClass.produce(
ReflectiveClassBuildItem.builder(uniqueClasses.toArray(new String[0])).constructors().methods().fields()
Expand Down Expand Up @@ -231,11 +228,9 @@ void runtimeInitializedClasses(BuildProducer<RuntimeInitializedPackageBuildItem>
net.sf.jasperreports.engine.fonts.AwtFontManager.class.getPackageName(),
net.sf.jasperreports.engine.type.ColorEnum.class.getPackageName(),
net.sf.jasperreports.engine.util.JRQueryExecuterUtils.class.getPackageName(),
net.sf.jasperreports.poi.query.PoiQueryExecuterFactoryBundle.class.getName(),
net.sf.jasperreports.xalan.data.XalanXmlDataSource.class.getPackageName(),
net.sf.jasperreports.xalan.util.XalanNsAwareXPathExecuter.class.getPackageName()).toList());
net.sf.jasperreports.poi.query.PoiQueryExecuterFactoryBundle.class.getName()).toList());
//@formatter:on
Log.debugf("Runtime: %s", classes);
Log.debugf("Jasper Runtime: %s", classes);
classes.stream()
.map(RuntimeInitializedPackageBuildItem::new)
.forEach(runtimeInitializedPackages::produce);
Expand Down Expand Up @@ -420,66 +415,6 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
}
}

private List<String> collectClassesInPackage(CombinedIndexBuildItem combinedIndex, String packageName) {
final List<String> classes = new ArrayList<>();
final List<DotName> packages = new ArrayList<>(combinedIndex.getIndex().getSubpackages(packageName));
packages.add(DotName.createSimple(packageName));
for (DotName aPackage : packages) {
final List<String> packageClasses = combinedIndex.getIndex()
.getClassesInPackage(aPackage)
.stream()
.map(ClassInfo::toString)
.toList();
classes.addAll(packageClasses);
}
Log.tracef("Package: %s", classes);
return classes;
}

private List<String> collectInterfacesInPackage(CombinedIndexBuildItem combinedIndex, String packageName) {
final List<String> classes = new ArrayList<>();
final List<DotName> packages = new ArrayList<>(combinedIndex.getIndex().getSubpackages(packageName));
packages.add(DotName.createSimple(packageName));
for (DotName aPackage : packages) {
final List<String> packageClasses = combinedIndex.getIndex()
.getClassesInPackage(aPackage)
.stream()
.filter(ClassInfo::isInterface) // Filter only interfaces
.map(ClassInfo::toString)
.toList();
classes.addAll(packageClasses);
}
Log.tracef("Package: %s", classes);
return classes;
}

private List<String> collectSubclasses(CombinedIndexBuildItem combinedIndex, String className) {
List<String> classes = combinedIndex.getIndex()
.getAllKnownSubclasses(DotName.createSimple(className))
.stream()
.map(ClassInfo::toString)
.collect(Collectors.toList());
classes.add(className);
Log.tracef("Subclasses: %s", classes);
return classes;
}

public List<String> collectImplementors(CombinedIndexBuildItem combinedIndex, String className) {
Set<String> classes = combinedIndex.getIndex()
.getAllKnownImplementors(DotName.createSimple(className))
.stream()
.map(ClassInfo::toString)
.collect(Collectors.toCollection(HashSet::new));
classes.add(className);
Set<String> subclasses = new HashSet<>();
for (String implementationClass : classes) {
subclasses.addAll(collectSubclasses(combinedIndex, implementationClass));
}
classes.addAll(subclasses);
Log.tracef("Implementors: %s", classes);
return new ArrayList<>(classes);
}

static Path findProjectRoot(Path outputDirectory) {
Path currentPath = outputDirectory.getParent();
Log.tracef("Current Directory: %s", currentPath);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedPackageBuildItem;
import io.quarkus.logging.Log;

/**
* A build step class responsible for registering classes related to the Jaxen library
* for reflection and runtime initialization during the Quarkus build process.
* <p>
* Jaxen supports 4 XML libs DOM, DOM4J, JDOM, XOM but we want to use native DOM so we exclude all the other 3rd party libs from
* classloading.
* </p>
*/
class JaxenProcessor extends AbstractJandexProcessor {

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

@BuildStep
void runtimeJaxenInitializedClasses(CombinedIndexBuildItem combinedIndex,
BuildProducer<RuntimeInitializedPackageBuildItem> runtimeInitializedPackages) {
//@formatter:off
List<String> classes = new ArrayList<>(Stream.of(
org.jaxen.dom4j.DocumentNavigator.class.getPackageName(),
org.jaxen.jdom.DocumentNavigator.class.getPackageName(),
org.jaxen.xom.DocumentNavigator.class.getPackageName()
).toList());
//@formatter:on
Log.warnf("Jaxen Runtime: %s", classes);
classes.stream()
.map(RuntimeInitializedPackageBuildItem::new)
.forEach(runtimeInitializedPackages::produce);
}

@BuildStep
void registerJaxenForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
CombinedIndexBuildItem combinedIndex) {
final List<String> classNames = new ArrayList<>(collectClassesInPackage(combinedIndex,
net.sf.jasperreports.jaxen.util.xml.JaxenXPathExecuterFactory.class.getPackageName()));
classNames.add(net.sf.jasperreports.jaxen.data.JaxenXmlDataSource.class.getName());
classNames.add(org.jaxen.saxpath.base.XPathReader.class.getName());

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

0 comments on commit c0263c7

Please sign in to comment.