This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch feat/union-types
in repository https://gitbox.apache.org/repos/asf/logging-log4j-tools.git

commit 8ca898466970d1d01d4aab57dc521c78c5059d97
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Fri May 30 13:01:35 2025 +0200

    log4j-docgen: Support attributes as a union of strict type and String
    
    This update enhances the generated XML schema by allowing each attribute to 
accept either its strict, expected type or a `${...}` expression. This 
accommodates use cases where property substitution is used, but at the same 
time allows IDE auto-completions.
    
    > [!WARNING]
    > This PR depends on #190 and should not be reviewed until that is merged.
    
    Closes #136
---
 .../log4j/docgen/generator/SchemaGenerator.java    | 130 +++++++--
 .../SchemaGeneratorTest/expected-plugins.xsd       | 298 ++++++++++++++-------
 src/changelog/.0.x.x/136_union-types.xml           |   8 +
 3 files changed, 314 insertions(+), 122 deletions(-)

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 707a606..c947be7 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
@@ -32,6 +32,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.inject.Named;
@@ -67,6 +68,24 @@ public final class SchemaGenerator {
 
     private static final String CHARSET_NAME = "UTF-8";
 
+    private static final String PROPERTY_SUBSTITUTION_TYPE = 
"property-substitution";
+    private static final String BOOLEAN_TYPE = "boolean";
+    private static final String STRING_TYPE = "string";
+    private static final ScalarType BOOLEAN_SCALAR_TYPE = new ScalarType();
+
+    static {
+        BOOLEAN_SCALAR_TYPE.setClassName(BOOLEAN_TYPE);
+        final Description description = new Description();
+        description.setText(
+                "A custom boolean type that allows `true`, `false`, or a 
property substitution expression.");
+        BOOLEAN_SCALAR_TYPE.setDescription(description);
+        for (final Boolean value : new Boolean[] {true, false}) {
+            final ScalarValue scalarValue = new ScalarValue();
+            scalarValue.setName(value.toString());
+            BOOLEAN_SCALAR_TYPE.addValue(scalarValue);
+        }
+    }
+
     private static final Map<String, String> XML_BUILTIN_TYPES = Map.ofEntries(
             entry(BigDecimal.class.getName(), "decimal"),
             entry(BigInteger.class.getName(), "integer"),
@@ -138,6 +157,12 @@ public final class SchemaGenerator {
     }
 
     private static void writeTypes(final TypeLookup lookup, final 
XMLStreamWriter writer) throws XMLStreamException {
+        writePropertySubstitutionType(writer);
+        // A union with member types `xsd:boolean` and 
`log4j:property-substitution` does not allow auto-completion
+        // in IDEs. This is why we define a `log4j:boolean` type from scratch.
+        writeScalarType(BOOLEAN_SCALAR_TYPE, writer);
+        writeUnionBuiltinTypes(writer);
+
         for (final ArtifactSourcedType sourcedType : lookup.values()) {
             final Type type = sourcedType.type;
             if (isBuiltinXmlType(type.getClassName())) {
@@ -167,12 +192,66 @@ public final class SchemaGenerator {
         return XML_BUILTIN_TYPES.containsKey(className);
     }
 
+    /**
+     * A restriction of {@code string} that requires at least one property 
substitution expression {@code ${...}}.
+     */
+    private static void writePropertySubstitutionType(final XMLStreamWriter 
writer) throws XMLStreamException {
+        writer.writeStartElement(XSD_NAMESPACE, "simpleType");
+        writer.writeAttribute("name", PROPERTY_SUBSTITUTION_TYPE);
+
+        writeDocumentation("A string with a property substitution 
expression.", writer);
+
+        writer.writeStartElement(XSD_NAMESPACE, "restriction");
+        writer.writeAttribute("base", "string");
+
+        writer.writeEmptyElement(XSD_NAMESPACE, "pattern");
+        writer.writeAttribute("value", ".*\\$\\{.*\\}.*");
+
+        writer.writeEndElement();
+        writer.writeEndElement();
+    }
+
+    /**
+     * Define types that are the union of a builtin type and {@value 
PROPERTY_SUBSTITUTION_TYPE}.
+     * <p>
+     *     IDEs don't propose auto-completion for these types.
+     * </p>
+     */
+    private static void writeUnionBuiltinTypes(final XMLStreamWriter writer) 
throws XMLStreamException {
+        final Collection<String> types = new 
TreeSet<>(XML_BUILTIN_TYPES.values());
+        // `xsd:string` is a superset of PROPERTY_SUBSTITUTION_TYPE, so no 
union is needed.
+        types.remove(STRING_TYPE);
+        // The union of `xsd:boolean` with PROPERTY_SUBSTITUTION_TYPE does not 
show auto-completion in IDEs.
+        // `log4j:boolean` will be generated from an _ad-hoc_ ScalarType 
definition in `base-log4j-types.xml`.
+        types.remove(BOOLEAN_TYPE);
+        for (final String type : types) {
+            writeUnionBuiltinType(type, writer);
+        }
+    }
+
+    private static void writeUnionBuiltinType(final String type, final 
XMLStreamWriter writer)
+            throws XMLStreamException {
+        writer.writeStartElement(XSD_NAMESPACE, "simpleType");
+        writer.writeAttribute("name", type);
+
+        writeDocumentation("Union of `xsd:" + type + "` and ` " + 
PROPERTY_SUBSTITUTION_TYPE + "`.", writer);
+
+        writer.writeEmptyElement(XSD_NAMESPACE, "union");
+        writer.writeAttribute("memberTypes", type + " log4j:" + 
PROPERTY_SUBSTITUTION_TYPE);
+
+        writer.writeEndElement();
+    }
+
     private static void writeScalarType(final ScalarType type, final 
XMLStreamWriter writer) throws XMLStreamException {
         writer.writeStartElement(XSD_NAMESPACE, "simpleType");
         writer.writeAttribute("name", type.getClassName());
 
         writeDocumentation(type.getDescription(), writer);
 
+        writer.writeStartElement(XSD_NAMESPACE, "union");
+        writer.writeAttribute("memberTypes", "log4j:" + 
PROPERTY_SUBSTITUTION_TYPE);
+        writer.writeStartElement(XSD_NAMESPACE, "simpleType");
+
         writer.writeStartElement(XSD_NAMESPACE, "restriction");
         writer.writeAttribute("base", "string");
 
@@ -182,6 +261,8 @@ public final class SchemaGenerator {
 
         writer.writeEndElement();
         writer.writeEndElement();
+        writer.writeEndElement();
+        writer.writeEndElement();
     }
 
     private static void writePluginType(
@@ -240,22 +321,30 @@ public final class SchemaGenerator {
     private static void writeDocumentation(@Nullable final Description 
description, final XMLStreamWriter writer)
             throws XMLStreamException {
         if (description != null) {
-            writer.writeStartElement(XSD_NAMESPACE, "annotation");
-            writer.writeStartElement(XSD_NAMESPACE, "documentation");
-            writer.writeCharacters(description.getText());
-            writer.writeEndElement();
-            writer.writeEndElement();
+            writeDocumentation(description.getText(), writer);
         }
     }
 
+    private static void writeDocumentation(final String text, final 
XMLStreamWriter writer) throws XMLStreamException {
+        writer.writeStartElement(XSD_NAMESPACE, "annotation");
+        writer.writeStartElement(XSD_NAMESPACE, "documentation");
+        writer.writeCharacters(text);
+        writer.writeEndElement();
+        writer.writeEndElement();
+    }
+
     private static void writeScalarValue(final ScalarValue value, final 
XMLStreamWriter writer)
             throws XMLStreamException {
-        writer.writeStartElement(XSD_NAMESPACE, "enumeration");
-        writer.writeAttribute("value", value.getName());
-
-        writeDocumentation(value.getDescription(), writer);
-
-        writer.writeEndElement();
+        final Description description = value.getDescription();
+        if (description != null) {
+            writer.writeStartElement(XSD_NAMESPACE, "enumeration");
+            writer.writeAttribute("value", value.getName());
+            writeDocumentation(value.getDescription(), writer);
+            writer.writeEndElement();
+        } else {
+            writer.writeEmptyElement(XSD_NAMESPACE, "enumeration");
+            writer.writeAttribute("value", value.getName());
+        }
     }
 
     private static void writePluginElement(
@@ -303,25 +392,28 @@ public final class SchemaGenerator {
     private static void writePluginAttribute(
             final TypeLookup lookup, final PluginAttribute attribute, final 
XMLStreamWriter writer)
             throws XMLStreamException {
-        @Nullable final String xmlType = getXmlType(lookup, 
attribute.getType());
-        if (xmlType == null) {
-            return;
+        final String xmlType = getXmlType(lookup, attribute.getType());
+        final Description description = attribute.getDescription();
+        if (description != null) {
+            writer.writeStartElement(XSD_NAMESPACE, "attribute");
+        } else {
+            writer.writeEmptyElement(XSD_NAMESPACE, "attribute");
         }
-        writer.writeStartElement(XSD_NAMESPACE, "attribute");
         writer.writeAttribute("name", attribute.getName());
-        writer.writeAttribute("type", xmlType);
-        final Description description = attribute.getDescription();
+        // If the type is unknown, use `string`
+        writer.writeAttribute("type", xmlType != null ? xmlType : "string");
         if (description != null) {
             writeDocumentation(description, writer);
+            writer.writeEndElement();
         }
-        writer.writeEndElement();
     }
 
     @Nullable
     private static String getXmlType(final TypeLookup lookup, final String 
className) {
         final String builtinType = XML_BUILTIN_TYPES.get(className);
         if (builtinType != null) {
-            return builtinType;
+            // Use the union types for all built-in types, except `string`.
+            return STRING_TYPE.equals(builtinType) ? STRING_TYPE : 
LOG4J_PREFIX + ":" + builtinType;
         }
         final ArtifactSourcedType type = lookup.get(className);
         return type != null ? LOG4J_PREFIX + ":" + className : null;
diff --git 
a/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd 
b/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd
index 4cd4cb3..ec9f788 100644
--- a/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd
+++ b/log4j-docgen/src/test/resources/SchemaGeneratorTest/expected-plugins.xsd
@@ -22,55 +22,138 @@
 <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">
+  <simpleType name="property-substitution">
     <annotation>
-      <documentation>Represents a logging level.
-NOTE: The Log4j API supports custom levels, the following list contains only 
the standard ones.</documentation>
+      <documentation>A string with a property substitution 
expression.</documentation>
     </annotation>
     <restriction base="string">
-      <enumeration value="OFF">
-        <annotation>
-          <documentation>Special level that disables logging.
-No events should be logged at this level.</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="FATAL">
-        <annotation>
-          <documentation>A fatal event that will prevent the application from 
continuing</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="ERROR">
-        <annotation>
-          <documentation>An error in the application, possibly 
recoverable</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="WARN">
-        <annotation>
-          <documentation>An event that might possible lead to an 
error</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="INFO">
-        <annotation>
-          <documentation>An event for informational purposes</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="DEBUG">
-        <annotation>
-          <documentation>A general debugging event</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="TRACE">
-        <annotation>
-          <documentation>A fine-grained debug message, typically capturing the 
flow through the application</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="ALL">
-        <annotation>
-          <documentation>Special level indicating all events should be 
logged</documentation>
-        </annotation>
-      </enumeration>
+      <pattern value=".*\$\{.*\}.*"/>
     </restriction>
   </simpleType>
+  <simpleType name="boolean">
+    <annotation>
+      <documentation>A custom boolean type that allows `true`, `false`, or a 
property substitution expression.
+      </documentation>
+    </annotation>
+    <union memberTypes="log4j:property-substitution">
+      <simpleType>
+        <restriction base="string">
+          <enumeration value="true"/>
+          <enumeration value="false"/>
+        </restriction>
+      </simpleType>
+    </union>
+  </simpleType>
+  <simpleType name="anyURI">
+    <annotation>
+      <documentation>Union of `xsd:anyURI` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="anyURI log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="byte">
+    <annotation>
+      <documentation>Union of `xsd:byte` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="byte log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="decimal">
+    <annotation>
+      <documentation>Union of `xsd:decimal` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="decimal log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="double">
+    <annotation>
+      <documentation>Union of `xsd:double` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="double log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="float">
+    <annotation>
+      <documentation>Union of `xsd:float` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="float log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="int">
+    <annotation>
+      <documentation>Union of `xsd:int` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="int log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="integer">
+    <annotation>
+      <documentation>Union of `xsd:integer` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="integer log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="long">
+    <annotation>
+      <documentation>Union of `xsd:long` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="long log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="short">
+    <annotation>
+      <documentation>Union of `xsd:short` and ` 
property-substitution`.</documentation>
+    </annotation>
+    <union memberTypes="short log4j:property-substitution"/>
+  </simpleType>
+  <simpleType name="org.apache.logging.log4j.Level">
+    <annotation>
+      <documentation>Represents a logging level.
+NOTE: The Log4j API supports custom levels, the following list contains only 
the standard ones.
+      </documentation>
+    </annotation>
+    <union memberTypes="log4j:property-substitution">
+      <simpleType>
+        <restriction base="string">
+          <enumeration value="OFF">
+            <annotation>
+              <documentation>Special level that disables logging.
+No events should be logged at this level.
+              </documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="FATAL">
+            <annotation>
+              <documentation>A fatal event that will prevent the application 
from continuing</documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="ERROR">
+            <annotation>
+              <documentation>An error in the application, possibly 
recoverable</documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="WARN">
+            <annotation>
+              <documentation>An event that might possible lead to an 
error</documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="INFO">
+            <annotation>
+              <documentation>An event for informational 
purposes</documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="DEBUG">
+            <annotation>
+              <documentation>A general debugging event</documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="TRACE">
+            <annotation>
+              <documentation>A fine-grained debug message, typically capturing 
the flow through the application
+              </documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="ALL">
+            <annotation>
+              <documentation>Special level indicating all events should be 
logged</documentation>
+            </annotation>
+          </enumeration>
+        </restriction>
+      </simpleType>
+    </union>
+  </simpleType>
   <group name="org.apache.logging.log4j.core.Appender">
     <annotation>
       <documentation>Appends log events.
@@ -104,23 +187,28 @@ It is recommended that, where possible, `Filter` 
implementations create a generi
     <annotation>
       <documentation>The result that can returned from a filter method 
call.</documentation>
     </annotation>
-    <restriction base="string">
-      <enumeration value="ACCEPT">
-        <annotation>
-          <documentation>The event will be processed without further filtering 
based on the log Level.</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="NEUTRAL">
-        <annotation>
-          <documentation>No decision could be made, further filtering should 
occur.</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="DENY">
-        <annotation>
-          <documentation>The event should not be processed.</documentation>
-        </annotation>
-      </enumeration>
-    </restriction>
+    <union memberTypes="log4j:property-substitution">
+      <simpleType>
+        <restriction base="string">
+          <enumeration value="ACCEPT">
+            <annotation>
+              <documentation>The event will be processed without further 
filtering based on the log Level.
+              </documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="NEUTRAL">
+            <annotation>
+              <documentation>No decision could be made, further filtering 
should occur.</documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="DENY">
+            <annotation>
+              <documentation>The event should not be processed.</documentation>
+            </annotation>
+          </enumeration>
+        </restriction>
+      </simpleType>
+    </union>
   </simpleType>
   <group name="org.apache.logging.log4j.core.Layout">
     <annotation>
@@ -152,23 +240,23 @@ It is recommended that, where possible, `Filter` 
implementations create a generi
 Must be unique.</documentation>
       </annotation>
     </attribute>
-    <attribute name="ignoreExceptions" type="boolean">
+    <attribute name="ignoreExceptions" type="log4j:boolean">
       <annotation>
         <documentation>If set to `false` logging exceptions will be forwarded 
to the caller.</documentation>
       </annotation>
     </attribute>
-    <attribute name="bufferedIo" type="boolean">
+    <attribute name="bufferedIo" type="log4j:boolean">
       <annotation>
         <documentation>If set to `true` (default) the appender will buffer 
messages before sending them.
 This attribute is ignored if `immediateFlush` is set to `true`.</documentation>
       </annotation>
     </attribute>
-    <attribute name="bufferSize" type="int">
+    <attribute name="bufferSize" type="log4j:int">
       <annotation>
         <documentation>Size in bytes of the appender's buffer.</documentation>
       </annotation>
     </attribute>
-    <attribute name="immediateFlush" type="boolean">
+    <attribute name="immediateFlush" type="log4j:boolean">
       <annotation>
         <documentation>If set to `true`, the appender flushes the output 
stream at each message and
 buffering is disabled regardless of the value of `bufferedIo`.</documentation>
@@ -184,18 +272,22 @@ buffering is disabled regardless of the value of 
`bufferedIo`.</documentation>
     <annotation>
       <documentation>Specifies the target of a console 
appender.</documentation>
     </annotation>
-    <restriction base="string">
-      <enumeration value="SYSTEM_OUT">
-        <annotation>
-          <documentation>Logs to the standard output.</documentation>
-        </annotation>
-      </enumeration>
-      <enumeration value="SYSTEM_ERR">
-        <annotation>
-          <documentation>Logs to the standard error.</documentation>
-        </annotation>
-      </enumeration>
-    </restriction>
+    <union memberTypes="log4j:property-substitution">
+      <simpleType>
+        <restriction base="string">
+          <enumeration value="SYSTEM_OUT">
+            <annotation>
+              <documentation>Logs to the standard output.</documentation>
+            </annotation>
+          </enumeration>
+          <enumeration value="SYSTEM_ERR">
+            <annotation>
+              <documentation>Logs to the standard error.</documentation>
+            </annotation>
+          </enumeration>
+        </restriction>
+      </simpleType>
+    </union>
   </simpleType>
   <complexType name="org.apache.logging.log4j.core.config.AppenderRef">
     <annotation>
@@ -283,7 +375,7 @@ If the provided value is invalid, then the default 
destination of standard out w
         <documentation>Name of the configuration</documentation>
       </annotation>
     </attribute>
-    <attribute name="monitorInterval" type="int">
+    <attribute name="monitorInterval" type="log4j:int">
       <annotation>
         <documentation>Number of seconds between polls for configuration 
changes</documentation>
       </annotation>
@@ -300,7 +392,7 @@ Possible values are `enable` and `disable`.
 The shutdown hook is enabled by default, unless Log4j detects the presence of 
the Servlet API.</documentation>
       </annotation>
     </attribute>
-    <attribute name="shutdownTimeout" type="int">
+    <attribute name="shutdownTimeout" type="log4j:int">
       <annotation>
         <documentation>Timeout in milliseconds of the logger context shut 
down</documentation>
       </annotation>
@@ -310,7 +402,7 @@ The shutdown hook is enabled by default, unless Log4j 
detects the presence of th
         <documentation>Sets the level of the status logger</documentation>
       </annotation>
     </attribute>
-    <attribute name="strict" type="boolean">
+    <attribute name="strict" type="log4j:boolean">
       <annotation>
         <documentation>If set to `true` the configuration file will be 
validated using an XML schema.</documentation>
       </annotation>
@@ -325,7 +417,7 @@ The shutdown hook is enabled by default, unless Log4j 
detects the presence of th
         <documentation>The name of the level.</documentation>
       </annotation>
     </attribute>
-    <attribute name="intLevel" type="int">
+    <attribute name="intLevel" type="log4j:int">
       <annotation>
         <documentation>An integer determines the strength of the custom level 
relative to the built-in levels.</documentation>
       </annotation>
@@ -369,7 +461,7 @@ The shutdown hook is enabled by default, unless Log4j 
detects the presence of th
         <documentation>The level of the logger.</documentation>
       </annotation>
     </attribute>
-    <attribute name="includeLocation" type="boolean">
+    <attribute name="includeLocation" type="log4j:boolean">
       <annotation>
         <documentation>When set to `false` location information will **not** 
be computed.
 
@@ -407,7 +499,7 @@ The default value depends on the logger context 
implementation: it is `false` fo
         <documentation>The level of the logger.</documentation>
       </annotation>
     </attribute>
-    <attribute name="includeLocation" type="boolean">
+    <attribute name="includeLocation" type="log4j:boolean">
       <annotation>
         <documentation>When set to `false` location information will **not** 
be computed.
 
@@ -474,12 +566,12 @@ Use this filter when you want to control the mean rate 
and maximum burst of log
         <documentation>Log events less specific than this level are filtered, 
while events with level equal or more specific always match.</documentation>
       </annotation>
     </attribute>
-    <attribute name="rate" type="float">
+    <attribute name="rate" type="log4j:float">
       <annotation>
         <documentation>Sets the average number of events per second to 
allow.</documentation>
       </annotation>
     </attribute>
-    <attribute name="maxBurst" type="long">
+    <attribute name="maxBurst" type="log4j:long">
       <annotation>
         <documentation>Sets the maximum number of events that can occur before 
events are filtered for exceeding the average rate.</documentation>
       </annotation>
@@ -505,24 +597,24 @@ A conversion pattern is composed of literal text and 
format control expressions
     <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="BigInteger" type="log4j:integer"/>
+    <attribute name="BigDecimal" type="log4j:decimal"/>
+    <attribute name="boolean" type="log4j:boolean"/>
+    <attribute name="Boolean" type="log4j:boolean"/>
+    <attribute name="byte" type="log4j:byte"/>
+    <attribute name="Byte" type="log4j:byte"/>
+    <attribute name="double" type="log4j:double"/>
+    <attribute name="Double" type="log4j:double"/>
+    <attribute name="float" type="log4j:float"/>
+    <attribute name="Float" type="log4j:float"/>
+    <attribute name="int" type="log4j:int"/>
+    <attribute name="Integer" type="log4j:int"/>
+    <attribute name="long" type="log4j:long"/>
+    <attribute name="Long" type="log4j:long"/>
+    <attribute name="short" type="log4j:short"/>
+    <attribute name="Short" type="log4j:short"/>
     <attribute name="String" type="string"/>
-    <attribute name="URI" type="anyURI"/>
-    <attribute name="URL" type="anyURI"/>
+    <attribute name="URI" type="log4j:anyURI"/>
+    <attribute name="URL" type="log4j:anyURI"/>
   </complexType>
 </schema>
\ No newline at end of file
diff --git a/src/changelog/.0.x.x/136_union-types.xml 
b/src/changelog/.0.x.x/136_union-types.xml
new file mode 100644
index 0000000..a9da4ff
--- /dev/null
+++ b/src/changelog/.0.x.x/136_union-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="added">
+  <issue id="136" 
link="https://github.com/apache/logging-log4j-tools/issues/136"/>
+  <description format="asciidoc">Add support for property substitution 
expressions in XML attributes.</description>
+</entry>

Reply via email to