[Git][java-team/wildfly-common][master] 6 commits: New upstream version 1.6.0

Markus Koschany (@apo) gitlab at salsa.debian.org
Sat Apr 30 13:45:06 BST 2022



Markus Koschany pushed to branch master at Debian Java Maintainers / wildfly-common


Commits:
2bf22b4a by Markus Koschany at 2022-04-30T14:35:53+02:00
New upstream version 1.6.0
- - - - -
6c311e1a by Markus Koschany at 2022-04-30T14:35:53+02:00
Update upstream source from tag 'upstream/1.6.0'

Update to upstream version '1.6.0'
with Debian dir 21d5664839278eb2ae1c492824ce7e73a3ceeb40
- - - - -
baf84b63 by Markus Koschany at 2022-04-30T14:36:22+02:00
Switch to debhelper-compat = 13.

- - - - -
81b82027 by Markus Koschany at 2022-04-30T14:36:37+02:00
Declare compliance with Debian Policy 4.6.0.

- - - - -
0c9078b2 by Markus Koschany at 2022-04-30T14:36:50+02:00
Update copyright years

- - - - -
52d61dff by Markus Koschany at 2022-04-30T14:37:34+02:00
Update changelog

- - - - -


22 changed files:

- debian/changelog
- debian/control
- debian/copyright
- pom.xml
- src/main/java/org/wildfly/common/_private/CommonMessages.java
- + src/main/java/org/wildfly/common/function/ThreadLocalStack.java
- + src/main/java/org/wildfly/common/iteration/CompositeIterable.java
- + src/main/java/org/wildfly/common/iteration/CompositeIterator.java
- src/main/java/org/wildfly/common/lock/SpinLock.java
- src/main/java/org/wildfly/common/net/Inet.java
- src/main/java/org/wildfly/common/selector/package-info.java
- + src/main/java/org/wildfly/common/xml/DocumentBuilderFactoryUtil.java
- + src/main/java/org/wildfly/common/xml/FactoryConstants.java
- + src/main/java/org/wildfly/common/xml/Log.java
- + src/main/java/org/wildfly/common/xml/SAXParserFactoryUtil.java
- + src/main/java/org/wildfly/common/xml/TransformerFactoryUtil.java
- + src/main/java/org/wildfly/common/xml/XMLInputFactoryUtil.java
- + src/main/java/org/wildfly/common/xml/XMLReaderFactoryUtil.java
- + src/main/java/org/wildfly/common/xml/package-info.java
- + src/test/java/org/wildfly/common/iteration/CompositeIterableTestCase.java
- + src/test/java/org/wildfly/common/iteration/CompositeIteratorTestCase.java
- + src/test/java/org/wildfly/common/xml/XmlFactoriesTest.java


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,11 @@
+wildfly-common (1.6.0-1) unstable; urgency=medium
+
+  * New upstream version 1.6.0.
+  * Switch to debhelper-compat = 13.
+  * Declare compliance with Debian Policy 4.6.0.
+
+ -- Markus Koschany <apo at debian.org>  Sat, 30 Apr 2022 14:37:15 +0200
+
 wildfly-common (1.5.4-1) unstable; urgency=medium
 
   * New upstream version 1.5.4.


=====================================
debian/control
=====================================
@@ -5,7 +5,7 @@ Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.or
 Uploaders:
  Markus Koschany <apo at debian.org>
 Build-Depends:
- debhelper-compat (= 12),
+ debhelper-compat (= 13),
  default-jdk,
  junit4,
  libgeronimo-annotation-1.3-spec-java,
@@ -14,7 +14,7 @@ Build-Depends:
  libmaven-bundle-plugin-java,
  libmaven-enforcer-plugin-java,
  maven-debian-helper (>= 2.1)
-Standards-Version: 4.5.0
+Standards-Version: 4.6.0
 Vcs-Git: https://salsa.debian.org/java-team/wildfly-common.git
 Vcs-Browser: https://salsa.debian.org/java-team/wildfly-common
 Homepage: http://wildfly.org/


=====================================
debian/copyright
=====================================
@@ -3,11 +3,11 @@ Upstream-Name: wildfly-common
 Source: https://github.com/wildfly/wildfly-common
 
 Files: *
-Copyright: 2014-2020, Red Hat, Inc.
+Copyright: 2014-2022, Red Hat, Inc.
 License: Apache-2.0
 
 Files: debian/*
-Copyright: 2017-2020, Markus Koschany <apo at debian.org>
+Copyright: 2017-2022, Markus Koschany <apo at debian.org>
 License: Apache-2.0
 
 License: Apache-2.0


=====================================
pom.xml
=====================================
@@ -25,12 +25,12 @@
 
     <groupId>org.wildfly.common</groupId>
     <artifactId>wildfly-common</artifactId>
-    <version>1.5.4.Final</version>
+    <version>1.6.0.Final</version>
 
     <parent>
         <groupId>org.jboss</groupId>
         <artifactId>jboss-parent</artifactId>
-        <version>34</version>
+        <version>39</version>
     </parent>
 
     <licenses>
@@ -118,10 +118,7 @@
                     <doctitle><![CDATA[WildFly Common ]]>${project.version}</doctitle>
                     <header><![CDATA[WildFly Common ]]>${project.version}</header>
                     <footer><![CDATA[WildFly Common ]]>${project.version}</footer>
-                    <bottom><![CDATA[<i>Copyright © 2019 JBoss, a division of Red Hat, Inc.</i>]]></bottom>
-                    <links>
-                        <link>https://docs.oracle.com/javase/8/docs/api/</link>
-                    </links>
+                    <bottom><![CDATA[<i>Copyright © 2018 JBoss, a division of Red Hat, Inc.</i>]]></bottom>
                     <doclint>none</doclint>
                     <additionalDependencies>
                         <additionalDependency>


=====================================
src/main/java/org/wildfly/common/_private/CommonMessages.java
=====================================
@@ -174,4 +174,6 @@ public interface CommonMessages {
 
     // 3000-3099 reserved for reference queue logging (see {@link org.wildfly.common.ref.Log})
 
+    // 3100-3199 reserved for xml factory logging (see {@link org.wildfly.common.xml.Log})
+
 }


=====================================
src/main/java/org/wildfly/common/function/ThreadLocalStack.java
=====================================
@@ -0,0 +1,50 @@
+package org.wildfly.common.function;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * A thread local stack data structure. In order to avoid memory churn the underlying
+ * ArrayDeque is never freed. If we remove the deque when it is empty then this results
+ * in excessive deque allocations.
+ */
+public class ThreadLocalStack<E> {
+
+    private static final Object NULL_VALUE = new Object();
+
+    private final ThreadLocal<Deque<Object>> deque = ThreadLocal.withInitial(ArrayDeque::new);
+
+    public void push(E item) {
+        Deque<Object> st = deque.get();
+        if(item == null) {
+            st.push(NULL_VALUE);
+        } else {
+            st.push(item);
+        }
+    }
+
+    public E peek() {
+        Deque<Object> st = deque.get();
+        Object o =  st.peek();
+        if(o == NULL_VALUE) {
+            return null;
+        } else {
+            return (E) o;
+        }
+    }
+
+    public E pop() {
+        Deque<Object> st = deque.get();
+        Object o =  st.pop();
+        if(o == NULL_VALUE) {
+            return null;
+        } else {
+            return (E) o;
+        }
+    }
+
+    public boolean isEmpty() {
+        return deque.get().isEmpty();
+    }
+
+}
\ No newline at end of file


=====================================
src/main/java/org/wildfly/common/iteration/CompositeIterable.java
=====================================
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wildfly.common.iteration;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * Used for iterating over an series of iterables, thus avoiding the need to allocate/populate a new list containing all elements.
+ * More efficient than the alternative when the number of iterables is arbitrary and small relative to the size of each iterable.
+ * @author Paul Ferraro
+ */
+public class CompositeIterable<T> implements Iterable<T> {
+
+    private final List<? extends Iterable<? extends T>> iterables;
+
+    /**
+     * Constructs a new composite iterable.
+     * @param iterables a series of iterables
+     */
+    @SafeVarargs
+    public CompositeIterable(Iterable<? extends T>... iterables) {
+        this(Arrays.asList(iterables));
+    }
+
+    /**
+     * Constructs a new composite iterable.
+     * @param iterables a series of iterables
+     */
+    public CompositeIterable(List<? extends Iterable<? extends T>> iterables) {
+        this.iterables = iterables;
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+        List<Iterator<? extends T>> iterators = new ArrayList<>(this.iterables.size());
+        for (Iterable<? extends T> elements : this.iterables) {
+            iterators.add(elements.iterator());
+        }
+        return new CompositeIterator<>(iterators);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 1;
+        for (Iterable<? extends T> elements : this.iterables) {
+            for (T element : elements) {
+                result = 31 * result + ((element != null) ? element.hashCode() : 0);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (!(object instanceof Iterable)) return false;
+        @SuppressWarnings("unchecked")
+        Iterator<Object> otherElements = ((Iterable<Object>) object).iterator();
+        for (Iterable<? extends T> iterable : this.iterables) {
+            Iterator<? extends T> elements = iterable.iterator();
+            while (elements.hasNext() && otherElements.hasNext()) {
+                elements.next().equals(otherElements.next());
+            }
+            if (elements.hasNext()) return false;
+        }
+        return !otherElements.hasNext();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append('[');
+        Iterator<? extends Iterable<? extends T>> iterables = this.iterables.iterator();
+        while (iterables.hasNext()) {
+            Iterator<? extends T> elements = iterables.next().iterator();
+            while (elements.hasNext()) {
+                if (builder.length() > 1) {
+                    builder.append(',').append(' ');
+                }
+                builder.append(elements.next());
+            }
+        }
+        return builder.append(']').toString();
+    }
+}


=====================================
src/main/java/org/wildfly/common/iteration/CompositeIterator.java
=====================================
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wildfly.common.iteration;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.function.Consumer;
+
+/**
+ * Iterator that iterates over a series of iterators.
+ * @author Paul Ferraro
+ */
+public class CompositeIterator<E> implements Iterator<E> {
+
+    private final Iterable<? extends Iterator<? extends E>> iterators;
+    private Iterator<? extends E> lastIterator;
+
+    /**
+     * Constructs a new composite iterator.
+     * @param iterators a series of iterators
+     */
+    @SafeVarargs
+    public CompositeIterator(Iterator<? extends E>... iterators) {
+        this(Arrays.asList(iterators));
+    }
+
+    /**
+     * Constructs a new composite iterator.
+     * @param iterators a series of iterators
+     */
+    public CompositeIterator(Iterable<? extends Iterator<? extends E>> iterators) {
+        this.iterators = iterators;
+    }
+
+    @Override
+    public boolean hasNext() {
+        for (Iterator<? extends E> iterator : this.iterators) {
+            if (iterator.hasNext()) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public E next() {
+        for (Iterator<? extends E> iterator : this.iterators) {
+            if (iterator.hasNext()) {
+                this.lastIterator = iterator;
+                return iterator.next();
+            }
+        }
+        throw new NoSuchElementException();
+    }
+
+    @Override
+    public void remove() {
+        Iterator<? extends E> iterator = this.lastIterator;
+        if (iterator == null) {
+            throw new IllegalStateException();
+        }
+        iterator.remove();
+    }
+
+    @Override
+    public void forEachRemaining(Consumer<? super E> action) {
+        for (Iterator<? extends E> iterator : this.iterators) {
+            while (iterator.hasNext()) {
+                action.accept(iterator.next());
+            }
+        }
+    }
+}


=====================================
src/main/java/org/wildfly/common/lock/SpinLock.java
=====================================
@@ -37,7 +37,7 @@ import org.wildfly.common.cpu.ProcessorInfo;
  */
 public class SpinLock implements ExtendedLock {
     private static final long ownerOffset;
-    private static final int spinLimit;
+    private static final int defaultSpinLimit;
 
     static {
         try {
@@ -45,7 +45,7 @@ public class SpinLock implements ExtendedLock {
         } catch (NoSuchFieldException e) {
             throw new NoSuchFieldError(e.getMessage());
         }
-        spinLimit = AccessController.doPrivileged(
+        defaultSpinLimit = AccessController.doPrivileged(
             (PrivilegedAction<Integer>) () -> Integer.valueOf(
                 System.getProperty("jboss.spin-lock.limit", ProcessorInfo.availableProcessors() == 1 ? "0" : "5000")
             )
@@ -57,10 +57,24 @@ public class SpinLock implements ExtendedLock {
 
     private int level;
 
+    private final int spinLimit;
+
     /**
      * Construct a new instance.
      */
-    public SpinLock() {}
+    public SpinLock() {
+        this(defaultSpinLimit);
+    }
+
+    /**
+     * Construct a new instance with the given spin limit.
+     *
+     * @param spinLimit the spin limit to use for this instance
+     */
+    public SpinLock(final int spinLimit) {
+        Assert.checkMinimumParameter("spinLimit", 0, spinLimit);
+        this.spinLimit = spinLimit;
+    }
 
     /**
      * Determine if this spin lock is held.  Useful for assertions.


=====================================
src/main/java/org/wildfly/common/net/Inet.java
=====================================
@@ -26,7 +26,9 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
+import java.net.ProtocolFamily;
 import java.net.SocketException;
+import java.net.StandardProtocolFamily;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.UnknownHostException;
@@ -969,6 +971,17 @@ public final class Inet {
         return new URI(scheme, null, host, port == defaultPort ? -1 : port, null, null, null);
     }
 
+    /**
+     * Get the protocol family of the given Internet address.
+     *
+     * @param inetAddress the address (must not be {@code null})
+     * @return the protocol family (not {@code null})
+     */
+    public static ProtocolFamily getProtocolFamily(InetAddress inetAddress) {
+        Assert.checkNotNullParam("inetAddress", inetAddress);
+        return inetAddress instanceof Inet6Address ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
+    }
+
     private static byte parseDecimal(String number) {
         int i = Integer.parseInt(number);
         if (i < 0 || i > 255) {


=====================================
src/main/java/org/wildfly/common/selector/package-info.java
=====================================
@@ -18,7 +18,5 @@
 
 /**
  * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
- *
- * @deprecated Use {@link org.wildfly.common.context.Contextual} instead.
  */
-package org.wildfly.common.selector;
\ No newline at end of file
+package org.wildfly.common.selector;


=====================================
src/main/java/org/wildfly/common/xml/DocumentBuilderFactoryUtil.java
=====================================
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wildfly.common.xml;
+
+import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
+import static org.wildfly.common.xml.FactoryConstants.APACHE_DISALLOW_DOCTYPE_DECL;
+import static org.wildfly.common.xml.FactoryConstants.APACHE_LOAD_EXTERNAL_DTD;
+import static org.wildfly.common.xml.FactoryConstants.XML_EXTERNAL_GENERAL_ENTITIES;
+import static org.wildfly.common.xml.FactoryConstants.XML_EXTERNAL_PARAMETER_ENTITIES;
+import static org.wildfly.common.xml.Log.XML_FACTORY_LOGGER;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.wildfly.common.annotation.NotNull;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Factory provides {@link DocumentBuilderFactory} with secure defaults set. Properties not supported generate a warning, but
+ * the factory process creation will continue and return a result.
+ * Settings based on recommendations of
+ * <a href="https://rules.sonarsource.com/java/RSPEC-2755">Sonarcloud RSPEC-2755</a> and
+ * <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java">OWASP XML
+ * External Entity Prevention Cheatsheet</a>.
+ * <p/>
+ *
+ * <ul>
+ * <li>{@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is set to true.</li>
+ * <li>{@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} is set to empty.</li>
+ * <li>{@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} is set to empty.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#APACHE_DISALLOW_DOCTYPE_DECL} is set to true.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#APACHE_LOAD_EXTERNAL_DTD} is set to false.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#XML_EXTERNAL_GENERAL_ENTITIES} is set to false.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#XML_EXTERNAL_PARAMETER_ENTITIES} is set to false.</li>
+ * <li>{@link javax.xml.parsers.DocumentBuilderFactory#setXIncludeAware(boolean)} is set to false.</li>
+ * <li>{@link javax.xml.parsers.DocumentBuilderFactory#setExpandEntityReferences(boolean)} is set to false.</li>
+ * </ul>
+ *
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ * @since 1.6.0.Final
+ */
+public final class DocumentBuilderFactoryUtil {
+
+    /*
+     * Prevent recurring log messages (per classloader).
+     */
+    private static final AtomicBoolean TO_BE_LOGGED = new AtomicBoolean(true);
+
+    /**
+     * Factory generated with secure defaults.
+     * @return an instance of the DocumentBuilderFactory.
+     */
+    @NotNull
+    public static DocumentBuilderFactory create() {
+        final DocumentBuilderFactory instance = DocumentBuilderFactory.newInstance();
+        final boolean toBeLogged = TO_BE_LOGGED.compareAndSet(true, false);
+
+        try {
+            instance.setFeature(FEATURE_SECURE_PROCESSING, true);
+        } catch (ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, FEATURE_SECURE_PROCESSING,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+        } catch (IllegalArgumentException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XMLConstants.ACCESS_EXTERNAL_DTD,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
+        } catch (IllegalArgumentException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XMLConstants.ACCESS_EXTERNAL_SCHEMA,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(APACHE_DISALLOW_DOCTYPE_DECL, true);
+        } catch (ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, APACHE_DISALLOW_DOCTYPE_DECL,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(APACHE_LOAD_EXTERNAL_DTD, false);
+        } catch (ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, APACHE_LOAD_EXTERNAL_DTD,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(XML_EXTERNAL_GENERAL_ENTITIES, false);
+        } catch (ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XML_EXTERNAL_GENERAL_ENTITIES,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(XML_EXTERNAL_PARAMETER_ENTITIES, false);
+        } catch (ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XML_EXTERNAL_PARAMETER_ENTITIES,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setXIncludeAware(false);
+        } catch (Exception e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, "setXIncludeAware(false)",
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setExpandEntityReferences(false);
+        } catch (Exception e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, "setExpandEntityReferences(false)",
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        return instance;
+    }
+
+    /**
+     * No instance.
+     */
+    private DocumentBuilderFactoryUtil() {
+        throw new IllegalStateException("No instance");
+    }
+
+}


=====================================
src/main/java/org/wildfly/common/xml/FactoryConstants.java
=====================================
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wildfly.common.xml;
+
+/**
+ * Constants to configure the factories.
+ * <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java">OWASP XML
+ * External Entity Prevention Cheatsheet</a>
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ * @since 1.6.0.Final
+ */
+final class FactoryConstants {
+
+    /**
+     * This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented
+     * Xerces 2 only:
+     * @see{https://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl}
+     */
+    public static final String APACHE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
+
+    /**
+     * If you can't completely disable DTDs, then at least do the following. This feature has to be used together with the
+     * following one (external-parameter-entities), otherwise it will not protect you from XXE for sure Do not include external
+     * general entities.
+     * Xerces 1:
+     * @see{https://xerces.apache.org/xerces-j/features.html#external-general-entities}
+     *
+     * Xerces 2:
+     * @see{https://xerces.apache.org/xerces2-j/features.html#external-general-entities}
+     */
+    public static final String XML_EXTERNAL_GENERAL_ENTITIES = "http://xml.org/sax/features/external-general-entities";
+
+    /**
+     * This feature has to be used together with the previous one(external-general-entities), otherwise it will not protect you from XXE for sure
+     *  Do not include external parameter entities or the external DTD subset.
+     * Xerces:
+     * @see{https://xerces.apache.org/xerces-j/features.html#external-parameter-entities}
+     *
+     * Xerces 2:
+     * @see{https://xerces.apache.org/xerces2-j/features.html#external-parameter-entities}
+     */
+    public static final String XML_EXTERNAL_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities";
+
+    /**
+     * Disable external DTDs as well.
+     */
+    public static final String APACHE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+
+    /**
+     * No instance.
+     */
+    private FactoryConstants() {
+        throw new IllegalStateException("No instance");
+    }
+
+}


=====================================
src/main/java/org/wildfly/common/xml/Log.java
=====================================
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2022 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wildfly.common.xml;
+
+import static org.jboss.logging.Logger.Level.WARN;
+
+import org.jboss.logging.BasicLogger;
+import org.jboss.logging.Logger;
+import org.jboss.logging.annotations.Cause;
+import org.jboss.logging.annotations.LogMessage;
+import org.jboss.logging.annotations.Message;
+import org.jboss.logging.annotations.MessageLogger;
+
+ at MessageLogger(projectCode = "COM", length = 5)
+interface Log extends BasicLogger {
+
+    Log XML_FACTORY_LOGGER = Logger.getMessageLogger(Log.class, "org.wildfly.common.xml");
+
+    // 3100-3199 reserved for xml factory logging
+    @LogMessage(level = WARN)
+    @Message(id = 3100, value = "Property or feature %s not supported by %s")
+    void xmlFactoryPropertyNotSupported(@Cause Throwable cause, String property, String factoryName);
+
+}


=====================================
src/main/java/org/wildfly/common/xml/SAXParserFactoryUtil.java
=====================================
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wildfly.common.xml;
+
+import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
+import static org.wildfly.common.xml.FactoryConstants.APACHE_DISALLOW_DOCTYPE_DECL;
+import static org.wildfly.common.xml.FactoryConstants.XML_EXTERNAL_GENERAL_ENTITIES;
+import static org.wildfly.common.xml.FactoryConstants.XML_EXTERNAL_PARAMETER_ENTITIES;
+import static org.wildfly.common.xml.Log.XML_FACTORY_LOGGER;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.wildfly.common.annotation.NotNull;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Factory provides {@link SAXParserFactory} with secure defaults set. Properties not supported generate a warning, but the
+ * factory process creation will continue and return a result.
+ * Settings based on recommendations of
+ * <a href="https://rules.sonarsource.com/java/RSPEC-2755">Sonarcloud RSPEC-2755</a> and
+ * <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java">OWASP XML
+ * External Entity Prevention Cheatsheet</a>.
+ * <p/>
+ * <ul>
+ * <li>{@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is set to true.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#APACHE_DISALLOW_DOCTYPE_DECL} is set to true.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#XML_EXTERNAL_GENERAL_ENTITIES} is set to false.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#XML_EXTERNAL_PARAMETER_ENTITIES} is set to false.</li>
+ * </ul>
+ *
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ * @since 1.6.0.Final
+ */
+public final class SAXParserFactoryUtil {
+
+    /*
+     * Prevent recurring log messages (per classloader).
+     */
+    private static final AtomicBoolean TO_BE_LOGGED = new AtomicBoolean(true);
+
+    @NotNull
+    public static SAXParserFactory create() {
+        final SAXParserFactory instance = SAXParserFactory.newInstance();
+        final boolean toBeLogged = TO_BE_LOGGED.compareAndSet(true, false);
+
+        try {
+            instance.setFeature(FEATURE_SECURE_PROCESSING, true);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, FEATURE_SECURE_PROCESSING,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(APACHE_DISALLOW_DOCTYPE_DECL, true);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, APACHE_DISALLOW_DOCTYPE_DECL,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(XML_EXTERNAL_GENERAL_ENTITIES, false);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XML_EXTERNAL_GENERAL_ENTITIES,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(XML_EXTERNAL_PARAMETER_ENTITIES, false);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XML_EXTERNAL_PARAMETER_ENTITIES,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        return instance;
+    }
+
+    /**
+     * No instance.
+     */
+    private SAXParserFactoryUtil() {
+        throw new IllegalStateException("No instance");
+    }
+}


=====================================
src/main/java/org/wildfly/common/xml/TransformerFactoryUtil.java
=====================================
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wildfly.common.xml;
+
+import org.wildfly.common.annotation.NotNull;
+
+import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
+import static javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD;
+import static javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET;
+import static org.wildfly.common.xml.Log.XML_FACTORY_LOGGER;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Factory provides {@link TransformerFactory} with secure defaults set. Properties not supported generate a warning, but the
+ * factory process creation will continue and return a result.
+ * Settings based on recommendations of
+ * <a href="https://rules.sonarsource.com/java/RSPEC-2755">Sonarcloud RSPEC-2755</a> and
+ * <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java">OWASP XML
+ * External Entity Prevention Cheatsheet</a>.
+ * <p/>
+ *
+ * <ul>
+ * <li>{@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is set to true.</li>
+ * <li>{@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} is set to empty.</li>
+ * <li>{@link javax.xml.XMLConstants#ACCESS_EXTERNAL_STYLESHEET} is set to empty.</li>
+ * </ul>
+ *
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ * @since 1.6.0.Final
+ */
+public final class TransformerFactoryUtil {
+
+    /*
+     * Prevent recurring log messages (per classloader).
+     */
+    private static final AtomicBoolean TO_BE_LOGGED = new AtomicBoolean(true);
+
+    @NotNull
+    public static TransformerFactory create() {
+        final TransformerFactory instance = TransformerFactory.newInstance();
+        final boolean toBeLogged = TO_BE_LOGGED.compareAndSet(true, false);
+
+        try {
+            instance.setFeature(FEATURE_SECURE_PROCESSING, true);
+        } catch (TransformerConfigurationException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, FEATURE_SECURE_PROCESSING,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setAttribute(ACCESS_EXTERNAL_DTD, "");
+        } catch (IllegalArgumentException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, ACCESS_EXTERNAL_DTD,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setAttribute(ACCESS_EXTERNAL_STYLESHEET, "");
+        } catch (IllegalArgumentException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, ACCESS_EXTERNAL_STYLESHEET,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        return instance;
+    }
+
+    /**
+     * No instance.
+     */
+    private TransformerFactoryUtil() {
+        throw new IllegalStateException("No instance");
+    }
+
+}


=====================================
src/main/java/org/wildfly/common/xml/XMLInputFactoryUtil.java
=====================================
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wildfly.common.xml;
+
+import static org.wildfly.common.xml.Log.XML_FACTORY_LOGGER;
+
+import javax.xml.stream.XMLInputFactory;
+
+import org.wildfly.common.annotation.NotNull;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Factory provides {@link XMLInputFactory} with secure defaults set. Properties not supported generate a warning, but the
+ * factory process creation will continue and return a result.
+ * Settings based on recommendations of
+ * <a href="https://rules.sonarsource.com/java/RSPEC-2755">Sonarcloud RSPEC-2755</a> and
+ * <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java">OWASP XML
+ * External Entity Prevention Cheatsheet</a>.
+ * <p/>
+ *
+ * <ul>
+ * <li>{@link javax.xml.stream.XMLInputFactory#SUPPORT_DTD} is set to false.</li>
+ * <li>{@link javax.xml.stream.XMLInputFactory#IS_SUPPORTING_EXTERNAL_ENTITIES} is set to false.</li>
+ * </ul>
+ *
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ * @since 1.6.0.Final
+ */
+public final class XMLInputFactoryUtil {
+
+    /*
+     * Prevent recurring log messages (per classloader).
+     */
+    private static final AtomicBoolean TO_BE_LOGGED = new AtomicBoolean(true);
+
+    /**
+     * Factory generated with secure defaults.
+     * @return an instance of the XMLInputFactory.
+     */
+    @NotNull
+    public static XMLInputFactory create() {
+        final XMLInputFactory instance = XMLInputFactory.newInstance();
+        final boolean toBeLogged = TO_BE_LOGGED.compareAndSet(true, false);
+
+        try {
+            instance.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
+        } catch (IllegalArgumentException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XMLInputFactory.SUPPORT_DTD,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
+        } catch (IllegalArgumentException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        return instance;
+    }
+
+    /**
+     * No instance.
+     */
+    private XMLInputFactoryUtil() {
+        throw new IllegalStateException("No instance");
+    }
+
+}


=====================================
src/main/java/org/wildfly/common/xml/XMLReaderFactoryUtil.java
=====================================
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wildfly.common.xml;
+
+import static org.wildfly.common.xml.FactoryConstants.APACHE_DISALLOW_DOCTYPE_DECL;
+import static org.wildfly.common.xml.FactoryConstants.APACHE_LOAD_EXTERNAL_DTD;
+import static org.wildfly.common.xml.FactoryConstants.XML_EXTERNAL_GENERAL_ENTITIES;
+import static org.wildfly.common.xml.FactoryConstants.XML_EXTERNAL_PARAMETER_ENTITIES;
+import static org.wildfly.common.xml.Log.XML_FACTORY_LOGGER;
+
+import org.wildfly.common.annotation.NotNull;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Factory provides {@link XMLReaderFactory} with secure defaults set. Properties not supported generate a warning, but the
+ * factory process creation will continue and return a result.
+ * Settings based on recommendations of
+ * <a href="https://rules.sonarsource.com/java/RSPEC-2755">Sonarcloud RSPEC-2755</a> and
+ * <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java">OWASP XML
+ * External Entity Prevention Cheatsheet</a>.
+ * <p/>
+ *
+ * <ul>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#APACHE_DISALLOW_DOCTYPE_DECL} is set to true.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#APACHE_LOAD_EXTERNAL_DTD} is set to false.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#XML_EXTERNAL_GENERAL_ENTITIES} is set to false.</li>
+ * <li>{@link org.wildfly.common.xml.FactoryConstants#XML_EXTERNAL_PARAMETER_ENTITIES} is set to false.</li>
+ * </ul>
+ *
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ * @since 1.6.0.Final
+ */
+public final class XMLReaderFactoryUtil {
+
+    /*
+     * Prevent recurring log messages (per classloader).
+     */
+    private static final AtomicBoolean TO_BE_LOGGED = new AtomicBoolean(true);
+
+    /**
+     * Factory generated with secure defaults.
+     * @return an instance of the XMLInputFactory.
+     */
+    @NotNull
+    public static XMLReader create() throws SAXException {
+        final XMLReader instance = XMLReaderFactory.createXMLReader();
+        final boolean toBeLogged = TO_BE_LOGGED.compareAndSet(true, false);
+
+        try {
+            instance.setFeature(APACHE_DISALLOW_DOCTYPE_DECL, true);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, APACHE_DISALLOW_DOCTYPE_DECL,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(APACHE_LOAD_EXTERNAL_DTD, false);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, APACHE_LOAD_EXTERNAL_DTD,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(XML_EXTERNAL_GENERAL_ENTITIES, false);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XML_EXTERNAL_GENERAL_ENTITIES,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        try {
+            instance.setFeature(XML_EXTERNAL_PARAMETER_ENTITIES, false);
+        } catch (SAXNotRecognizedException | SAXNotSupportedException e) {
+            if (toBeLogged) {
+                XML_FACTORY_LOGGER.xmlFactoryPropertyNotSupported(e, XML_EXTERNAL_PARAMETER_ENTITIES,
+                        instance.getClass().getCanonicalName());
+            }
+        }
+
+        return instance;
+    }
+
+    /**
+     * No instance.
+     */
+    private XMLReaderFactoryUtil() {
+        throw new IllegalStateException("No instance");
+    }
+
+}


=====================================
src/main/java/org/wildfly/common/xml/package-info.java
=====================================
@@ -0,0 +1,25 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2022 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Classes which create XML related factories with safe defaults.
+ *
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ */
+
+package org.wildfly.common.xml;


=====================================
src/test/java/org/wildfly/common/iteration/CompositeIterableTestCase.java
=====================================
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wildfly.common.iteration;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link CompositeIterable}.
+ * @author Paul Ferraro
+ */
+public class CompositeIterableTestCase {
+
+    @Test
+    public void test() {
+        List<Integer> expected = IntStream.range(0, 10).mapToObj(Integer::valueOf).collect(Collectors.toList());
+
+        test(expected, new CompositeIterable<>(new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4)), Arrays.asList(5, 6, 7, 8, 9)));
+        test(expected, new CompositeIterable<>(new ArrayList<>(Arrays.asList(0, 1)), Arrays.asList(2, 3), Arrays.asList(4, 5), Arrays.asList(6, 7), Arrays.asList(8, 9)));
+        test(expected, new CompositeIterable<>(Collections.emptyList(), new ArrayList<>(expected), Collections.emptyList()));
+    }
+
+    @Test
+    public void testRemove() {
+        
+    }
+
+    static void test(Iterable<Integer> expected, Iterable<Integer> subject) {
+        Assert.assertEquals(expected.hashCode(), subject.hashCode());
+        Assert.assertEquals(expected.toString(), subject.toString());
+
+        Iterator<Integer> subjectIterator = subject.iterator();
+        Iterator<Integer> expectedIterator = expected.iterator();
+        while (expectedIterator.hasNext()) {
+            Assert.assertTrue(subjectIterator.hasNext());
+            Assert.assertEquals(expectedIterator.next(), subjectIterator.next());
+        }
+        Assert.assertFalse(subjectIterator.hasNext());
+    }
+}


=====================================
src/test/java/org/wildfly/common/iteration/CompositeIteratorTestCase.java
=====================================
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wildfly.common.iteration;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link CompositeIterator}.
+ * @author Paul Ferraro
+ */
+public class CompositeIteratorTestCase {
+
+    @Test
+    public void remove() {
+        List<Integer> list = new ArrayList<>(IntStream.range(0, 10).mapToObj(Integer::valueOf).collect(Collectors.toList()));
+        Iterator<Integer> iterator = new CompositeIterator<>(Collections.<Integer>emptyList().iterator(), list.iterator(), Collections.<Integer>emptyList().iterator());
+
+        try {
+            iterator.remove();
+            Assert.fail("remove() should fail before first call to next()");
+        } catch (IllegalStateException e) {
+            // Expected
+        }
+
+        IntStream.range(0, 10).forEach(i -> {
+            Assert.assertTrue(iterator.hasNext());
+            Assert.assertEquals(i, iterator.next().intValue());
+            iterator.remove();
+        });
+        Assert.assertFalse(iterator.hasNext());
+
+        try {
+            iterator.next();
+            Assert.fail("next() should fail when hasNext() = false");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        Assert.assertTrue(list.isEmpty());
+    }
+
+
+    @Test
+    public void forEachRemaining() {
+        List<Integer> list1 = IntStream.range(0, 5).mapToObj(Integer::valueOf).collect(Collectors.toList());
+        List<Integer> list2 = IntStream.range(5, 10).mapToObj(Integer::valueOf).collect(Collectors.toList());
+        Iterator<Integer> iterator = new CompositeIterator<>(Collections.<Integer>emptyList().iterator(), list1.iterator(), list2.iterator(), Collections.<Integer>emptyList().iterator());
+
+        Assert.assertTrue(iterator.hasNext());
+        // Skip 0
+        iterator.next();
+        Assert.assertTrue(iterator.hasNext());
+
+        int expected = IntStream.range(1, 10).reduce(1, Math::multiplyExact);
+        AtomicInteger result = new AtomicInteger(1);
+        iterator.forEachRemaining(value -> result.accumulateAndGet(value, Math::multiplyExact));
+        Assert.assertEquals(expected, result.get());
+
+        // Iterator should be drained
+        Assert.assertFalse(iterator.hasNext());
+
+        try {
+            iterator.next();
+            Assert.fail("next() should fail when hasNext() = false");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
+}


=====================================
src/test/java/org/wildfly/common/xml/XmlFactoriesTest.java
=====================================
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wildfly.common.xml;
+
+import static org.junit.Assert.assertNotNull;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+
+import org.junit.Test;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+
+/**
+ * @author <a href="mailto:boris at unckel.net">Boris Unckel</a>
+ *
+ */
+public class XmlFactoriesTest {
+
+    @Test
+    public void testDocumentBuilderFactoryUtil() throws ParserConfigurationException {
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactoryUtil.create();
+        assertNotNull(documentBuilderFactory);
+        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+        assertNotNull(documentBuilder);
+    }
+
+    @Test
+    public void testSAXParserFactoryUtil() throws ParserConfigurationException, SAXException {
+        SAXParserFactory saxParserFactory = SAXParserFactoryUtil.create();
+        assertNotNull(saxParserFactory);
+        SAXParser saxParser = saxParserFactory.newSAXParser();
+        assertNotNull(saxParser);
+    }
+
+    @Test
+    public void testTransformerFactoryUtil() throws TransformerConfigurationException {
+        TransformerFactory transformerFactory = TransformerFactoryUtil.create();
+        assertNotNull(transformerFactory);
+        Transformer transformer = transformerFactory.newTransformer();
+        assertNotNull(transformer);
+    }
+
+    @Test
+    public void testXMLInputFactoryUtil() {
+        XMLInputFactory xmlInputFactory = XMLInputFactoryUtil.create();
+        assertNotNull(xmlInputFactory);
+    }
+
+    @Test
+    public void testXMLReaderFactoryUtil() throws SAXException {
+        XMLReader xmlReader = XMLReaderFactoryUtil.create();
+        assertNotNull(xmlReader);
+    }
+
+}



View it on GitLab: https://salsa.debian.org/java-team/wildfly-common/-/compare/1ccf7e65af5e39695e1832e3c5290f654b8bb721...52d61dffe9400745d8717852103ff11280212d4b

-- 
View it on GitLab: https://salsa.debian.org/java-team/wildfly-common/-/compare/1ccf7e65af5e39695e1832e3c5290f654b8bb721...52d61dffe9400745d8717852103ff11280212d4b
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20220430/a077a79d/attachment.htm>


More information about the pkg-java-commits mailing list