From 0782606cad5f735c9d04ea78f4664766c0603f26 Mon Sep 17 00:00:00 2001 From: olivier dufour Date: Fri, 20 Nov 2020 21:33:11 +0100 Subject: [PATCH] add characterEscapeHandler and TypedXmlWriter xmlseeAlso support and fix separator in jaxb index file --- .../jaxb/deployment/JaxbProcessor.java | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java index 25907901934b47..8e6b16ceb37caa 100644 --- a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java +++ b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java @@ -3,11 +3,15 @@ import java.io.IOError; import java.io.IOException; import java.lang.annotation.Annotation; +import java.lang.reflect.Modifier; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Stream; import javax.inject.Inject; @@ -47,8 +51,11 @@ import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget.Kind; +import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; +import org.jboss.jandex.Type; import com.sun.xml.bind.v2.model.annotation.Locatable; @@ -56,6 +63,7 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.IndexDependencyBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem; @@ -107,6 +115,7 @@ class JaxbProcessor { private static final DotName XML_SCHEMA = DotName.createSimple(XmlSchema.class.getName()); private static final DotName XML_JAVA_TYPE_ADAPTER = DotName.createSimple(XmlJavaTypeAdapter.class.getName()); private static final DotName XML_ANY_ELEMENT = DotName.createSimple(XmlAnyElement.class.getName()); + private static final DotName XML_SEE_ALSO = DotName.createSimple(XmlSeeAlso.class.getName()); private static final List JAXB_ROOT_ANNOTATIONS = Arrays.asList(XML_ROOT_ELEMENT, XML_TYPE, XML_REGISTRY); @@ -169,6 +178,18 @@ void processAnnotationsAndIndexFiles( proxyDefinitions.produce(new NativeImageProxyDefinitionBuildItem(className, Locatable.class.getName())); addReflectiveClass(reflectiveClass, true, false, className); }); + produceProxyIfExist(proxyDefinitions, "com.sun.xml.bind.marshaller.CharacterEscapeHandler"); + produceProxyIfExist(proxyDefinitions, "com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler"); + produceProxyIfExist(proxyDefinitions, "org.glassfish.jaxb.core.marshaller.CharacterEscapeHandler"); + produceProxyIfExist(proxyDefinitions, "com.sun.xml.txw2.output.CharacterEscapeHandler"); + produceProxyIfExist(proxyDefinitions, "org.glassfish.jaxb.characterEscapeHandler"); + produceProxyIfExist(proxyDefinitions, "org.glassfish.jaxb.marshaller.CharacterEscapeHandler"); + + proxyDefinitions.produce(new NativeImageProxyDefinitionBuildItem("com.sun.xml.txw2.TypedXmlWriter")); + Set proxiesCreated = new HashSet<>(); + DotName typedXmlWriterDN = DotName.createSimple("com.sun.xml.txw2.TypedXmlWriter"); + // getAllKnownDirectImplementors skip interface, so use own recursion + produceRecursiveProxies(index, typedXmlWriterDN, proxyDefinitions, proxiesCreated); for (JaxbFileRootBuildItem i : fileRoots) { try (Stream stream = iterateResources(i.getFileRoot())) { @@ -178,6 +199,50 @@ void processAnnotationsAndIndexFiles( } } + private void produceProxyIfExist(BuildProducer proxies, String s) { + try { + Class.forName(s); + proxies.produce(new NativeImageProxyDefinitionBuildItem(s)); + } catch (ClassNotFoundException e) { + //silent fail + } + } + + @BuildStep + void seeAlso(CombinedIndexBuildItem combinedIndexBuildItem, + BuildProducer reflectiveItems) { + IndexView index = combinedIndexBuildItem.getIndex(); + for (AnnotationInstance xmlSeeAlsoAnn : index.getAnnotations(XML_SEE_ALSO)) { + AnnotationValue value = xmlSeeAlsoAnn.value(); + Type[] types = value.asClassArray(); + for (Type t : types) { + reflectiveItems.produce(new ReflectiveClassBuildItem(false, false, t.name().toString())); + } + } + } + + void produceRecursiveProxies(IndexView index, + DotName interfaceDN, + BuildProducer proxies, Set proxiesCreated) { + index.getKnownDirectImplementors(interfaceDN).stream() + .filter(classinfo -> Modifier.isInterface(classinfo.flags())) + .map(ClassInfo::name) + .forEach((className) -> { + if (!proxiesCreated.contains(className.toString())) { + proxies.produce(new NativeImageProxyDefinitionBuildItem(className.toString())); + produceRecursiveProxies(index, className, proxies, proxiesCreated); + proxiesCreated.add(className.toString()); + } + }); + + } + + @BuildStep + void addDependencies(BuildProducer indexDependency) { + indexDependency.produce(new IndexDependencyBuildItem("org.glassfish.jaxb", "txw2")); + indexDependency.produce(new IndexDependencyBuildItem("org.glassfish.jaxb", "jaxb-runtime")); + } + @BuildStep void registerClasses( BuildProducer nativeImageProps, @@ -210,7 +275,8 @@ private void handleJaxbFile(Path p, BuildProducer BuildProducer reflectiveClass) { try { String path = p.toAbsolutePath().toString().substring(1); - String pkg = p.toAbsolutePath().getParent().toString().substring(1).replace("/", ".") + "."; + String pkg = p.toAbsolutePath().getParent().toString().substring(1) + .replace(FileSystems.getDefault().getSeparator(), ".") + "."; resource.produce(new NativeImageResourceBuildItem(path));