[Git][java-team/wildfly-common][upstream] New upstream version 1.6.0
Markus Koschany (@apo)
gitlab at salsa.debian.org
Sat Apr 30 13:45:19 BST 2022
Markus Koschany pushed to branch upstream 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
- - - - -
19 changed files:
- 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:
=====================================
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/-/commit/2bf22b4acabb85a84983161a62af0eb7b04975de
--
View it on GitLab: https://salsa.debian.org/java-team/wildfly-common/-/commit/2bf22b4acabb85a84983161a62af0eb7b04975de
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/6f46bd01/attachment.htm>
More information about the pkg-java-commits
mailing list