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>