log4j-docgen: Support boxed and native Java types in XSD generation (#190)
Previously, `SchemaGenerator` did not handle configuration attributes with boxed types (e.g., `Integer`, `Boolean`), leading to their omission from the generated XSD schema.
This update introduces:
* Support for boxed Java types as configuration attributes.
* Improved handling of other native Java types that map to XML built-in data types (e.g., `BigDecimal`, `URL`).
These enhancements ensure that all relevant configuration attributes are accurately represented in the schema.
Fixes: #135
diff --git a/log4j-docgen/src/main/java/org/apache/logging/log4j/docgen/generator/SchemaGenerator.java b/log4j-docgen/src/main/java/org/apache/logging/log4j/docgen/generator/SchemaGenerator.java
index e2874c3..707a606 100644
--- a/log4j-docgen/src/main/java/org/apache/logging/log4j/docgen/generator/SchemaGenerator.java
+++ b/log4j-docgen/src/main/java/org/apache/logging/log4j/docgen/generator/SchemaGenerator.java
@@ -16,15 +16,21 @@
*/
package org.apache.logging.log4j.docgen.generator;
+import static java.util.Map.entry;
import static java.util.Objects.requireNonNull;
import java.io.IOException;
import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -61,6 +67,27 @@
private static final String CHARSET_NAME = "UTF-8";
+ private static final Map<String, String> XML_BUILTIN_TYPES = Map.ofEntries(
+ entry(BigDecimal.class.getName(), "decimal"),
+ entry(BigInteger.class.getName(), "integer"),
+ entry(boolean.class.getName(), "boolean"),
+ entry(Boolean.class.getName(), "boolean"),
+ entry(byte.class.getName(), "byte"),
+ entry(Byte.class.getName(), "byte"),
+ entry(double.class.getName(), "double"),
+ entry(Double.class.getName(), "double"),
+ entry(float.class.getName(), "float"),
+ entry(Float.class.getName(), "float"),
+ entry(int.class.getName(), "int"),
+ entry(Integer.class.getName(), "int"),
+ entry(short.class.getName(), "short"),
+ entry(Short.class.getName(), "short"),
+ entry(String.class.getName(), "string"),
+ entry(long.class.getName(), "long"),
+ entry(Long.class.getName(), "long"),
+ entry(URI.class.getName(), "anyURI"),
+ entry(URL.class.getName(), "anyURI"));
+
private SchemaGenerator() {}
public static void generateSchema(final SchemaGeneratorArgs args) throws XMLStreamException {
@@ -137,19 +164,7 @@
}
private static boolean isBuiltinXmlType(final String className) {
- switch (className) {
- case "boolean":
- case "byte":
- case "double":
- case "float":
- case "int":
- case "short":
- case "long":
- case "java.lang.String":
- return true;
- default:
- return false;
- }
+ return XML_BUILTIN_TYPES.containsKey(className);
}
private static void writeScalarType(final ScalarType type, final XMLStreamWriter writer) throws XMLStreamException {
@@ -304,23 +319,12 @@
@Nullable
private static String getXmlType(final TypeLookup lookup, final String className) {
- switch (className) {
- case "boolean":
- case "byte":
- case "double":
- case "float":
- case "int":
- case "short":
- case "long":
- return className;
- case "java.lang.String":
- return "string";
+ final String builtinType = XML_BUILTIN_TYPES.get(className);
+ if (builtinType != null) {
+ return builtinType;
}
final ArtifactSourcedType type = lookup.get(className);
- if (type != null) {
- return LOG4J_PREFIX + ":" + className;
- }
- return null;
+ return type != null ? LOG4J_PREFIX + ":" + className : null;
}
private static void writeMultiplicity(
diff --git a/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd b/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd
index ee0d568..4cd4cb3 100644
--- a/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd
+++ b/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd
@@ -19,7 +19,8 @@
~ This is a test schema used in `SchemaGeneratorTest`.
~ Unlike this file the `SchemaGenerator` strips whitespace.
-->
-<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:log4j="https://logging.apache.org/xml/ns" elementFormDefault="qualified" targetNamespace="https://logging.apache.org/xml/ns" version="1.2.3">
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:log4j="https://logging.apache.org/xml/ns"
+ elementFormDefault="qualified" targetNamespace="https://logging.apache.org/xml/ns" version="1.2.3">
<element type="log4j:org.apache.logging.log4j.core.config.Configuration" name="Configuration"/>
<simpleType name="org.apache.logging.log4j.Level">
<annotation>
@@ -500,4 +501,28 @@
</annotation>
</attribute>
</complexType>
+ <complexType name="org.apache.logging.log4j.dummy.AllTypesPlugin">
+ <annotation>
+ <documentation>Dummy plugin to test all types of builtin XML attributes.</documentation>
+ </annotation>
+ <attribute name="BigInteger" type="integer"/>
+ <attribute name="BigDecimal" type="decimal"/>
+ <attribute name="boolean" type="boolean"/>
+ <attribute name="Boolean" type="boolean"/>
+ <attribute name="byte" type="byte"/>
+ <attribute name="Byte" type="byte"/>
+ <attribute name="double" type="double"/>
+ <attribute name="Double" type="double"/>
+ <attribute name="float" type="float"/>
+ <attribute name="Float" type="float"/>
+ <attribute name="int" type="int"/>
+ <attribute name="Integer" type="int"/>
+ <attribute name="long" type="long"/>
+ <attribute name="Long" type="long"/>
+ <attribute name="short" type="short"/>
+ <attribute name="Short" type="short"/>
+ <attribute name="String" type="string"/>
+ <attribute name="URI" type="anyURI"/>
+ <attribute name="URL" type="anyURI"/>
+ </complexType>
</schema>
\ No newline at end of file
diff --git a/log4j-docgen/src/test/resources/SchemaGeneratorTest/plugins.xml b/log4j-docgen/src/test/resources/SchemaGeneratorTest/plugins.xml
index b610c00..2f6f696 100644
--- a/log4j-docgen/src/test/resources/SchemaGeneratorTest/plugins.xml
+++ b/log4j-docgen/src/test/resources/SchemaGeneratorTest/plugins.xml
@@ -267,6 +267,31 @@
</attribute>
</attributes>
</plugin>
+
+ <plugin name="AllTypes" className="org.apache.logging.log4j.dummy.AllTypesPlugin">
+ <description>Dummy plugin to test all types of builtin XML attributes.</description>
+ <attributes>
+ <attribute name="BigInteger" type="java.math.BigInteger"/>
+ <attribute name="BigDecimal" type="java.math.BigDecimal"/>
+ <attribute name="boolean" type="boolean"/>
+ <attribute name="Boolean" type="java.lang.Boolean"/>
+ <attribute name="byte" type="byte"/>
+ <attribute name="Byte" type="java.lang.Byte"/>
+ <attribute name="double" type="double"/>
+ <attribute name="Double" type="java.lang.Double"/>
+ <attribute name="float" type="float"/>
+ <attribute name="Float" type="java.lang.Float"/>
+ <attribute name="int" type="int"/>
+ <attribute name="Integer" type="java.lang.Integer"/>
+ <attribute name="long" type="long"/>
+ <attribute name="Long" type="java.lang.Long"/>
+ <attribute name="short" type="short"/>
+ <attribute name="Short" type="java.lang.Short"/>
+ <attribute name="String" type="java.lang.String"/>
+ <attribute name="URI" type="java.net.URI"/>
+ <attribute name="URL" type="java.net.URL"/>
+ </attributes>
+ </plugin>
</plugins>
<abstractTypes>
diff --git a/src/changelog/.0.x.x/135_native-types.xml b/src/changelog/.0.x.x/135_native-types.xml
new file mode 100644
index 0000000..5b4d83f
--- /dev/null
+++ b/src/changelog/.0.x.x/135_native-types.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://logging.apache.org/xml/ns"
+ xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="fixed">
+ <issue id="135" link="https://github.com/apache/logging-log4j-tools/issues/135"/>
+ <description format="asciidoc">Fix support of boxed and native Java types in XSD generation.</description>
+</entry>