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

coheigea pushed a commit to branch coheigea/walker
in repository https://gitbox.apache.org/repos/asf/ws-xmlschema.git

commit 2efdd7c667f267be56ac49f0a345485b27f8043d
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Fri Sep 25 10:37:33 2026 +0100

    The walker changes the schema model
---
 .../ws/commons/schema/walker/XmlSchemaScope.java   |  21 ++--
 .../walker/UnionMembersUnchangedByWalkTest.java    | 116 +++++++++++++++++++++
 2 files changed, 127 insertions(+), 10 deletions(-)

diff --git 
a/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java
 
b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java
index f7cb595f..bb354b0d 100644
--- 
a/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java
+++ 
b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java
@@ -247,24 +247,25 @@ final class XmlSchemaScope {
         } else if (content instanceof XmlSchemaSimpleTypeUnion) {
             XmlSchemaSimpleTypeUnion union = (XmlSchemaSimpleTypeUnion)content;
             QName[] namedBaseTypes = union.getMemberTypesQNames();
-            List<XmlSchemaSimpleType> baseTypes = union.getBaseTypes();
 
-            if (namedBaseTypes != null) {
-                if (baseTypes == null) {
-                    baseTypes = new 
ArrayList<XmlSchemaSimpleType>(namedBaseTypes.length);
-                }
+            /*
+             * A copy of the inline members, to which the named ones are 
added. Adding them to the
+             * union's own list would change the schema model, and again on 
every walk of it.
+             */
+            final List<XmlSchemaSimpleType> baseTypes = new 
ArrayList<XmlSchemaSimpleType>();
+            if (union.getBaseTypes() != null) {
+                baseTypes.addAll(union.getBaseTypes());
+            }
 
+            if (namedBaseTypes != null) {
                 for (QName namedBaseType : namedBaseTypes) {
                     baseTypes.add(simpleTypeByName(namedBaseType, "member type 
of union",
                                                    getName(simpleType, 
"{Anonymous Union Type}")));
                 }
             }
 
-            /*
-             * baseTypes cannot be null at this point; there must be a union of
-             * types.
-             */
-            if ((baseTypes == null) || baseTypes.isEmpty()) {
+            // There must be a union of types.
+            if (baseTypes.isEmpty()) {
                 throw new XmlSchemaException("The union "
                                              + getName(simpleType, "{Anonymous 
Union Type}")
                                              + " has no member types.");
diff --git 
a/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/UnionMembersUnchangedByWalkTest.java
 
b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/UnionMembersUnchangedByWalkTest.java
new file mode 100644
index 00000000..d12fd179
--- /dev/null
+++ 
b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/UnionMembersUnchangedByWalkTest.java
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ws.commons.schema.walker;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaSimpleType;
+import org.apache.ws.commons.schema.XmlSchemaSimpleTypeUnion;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Walking a schema must not change it. The walker once added a union's named 
member types to
+ * the union's own list of inline members, so the list grew on every walk, and 
within one walk
+ * on every visit to an anonymous union.
+ */
+public class UnionMembersUnchangedByWalkTest extends Assert {
+
+    private static final String NS = "urn:union";
+
+    private static final String SCHEMA =
+        "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"; 
xmlns:tns=\"urn:union\""
+        + " targetNamespace=\"urn:union\">"
+        + "<xs:simpleType name=\"U\"><xs:union memberTypes=\"xs:int 
xs:boolean\">"
+        + "<xs:simpleType><xs:restriction base=\"xs:string\"/></xs:simpleType>"
+        + "</xs:union></xs:simpleType>"
+        + "<xs:attribute name=\"a\"><xs:simpleType>"
+        + "<xs:union memberTypes=\"xs:int 
xs:date\"/></xs:simpleType></xs:attribute>"
+        + "<xs:complexType name=\"T1\"><xs:attribute 
ref=\"tns:a\"/></xs:complexType>"
+        + "<xs:complexType name=\"T2\"><xs:attribute 
ref=\"tns:a\"/></xs:complexType>"
+        + "<xs:complexType name=\"T3\"><xs:attribute 
ref=\"tns:a\"/></xs:complexType>"
+        + "<xs:element name=\"root\"><xs:complexType><xs:sequence>"
+        + "<xs:element name=\"u\" type=\"tns:U\"/>"
+        + "<xs:element name=\"t1\" type=\"tns:T1\"/>"
+        + "<xs:element name=\"t2\" type=\"tns:T2\"/>"
+        + "<xs:element name=\"t3\" type=\"tns:T3\"/>"
+        + "</xs:sequence></xs:complexType></xs:element>"
+        + "</xs:schema>";
+
+    @Test
+    public void testRepeatedWalksLeaveUnionMembersUnchanged() {
+        XmlSchemaCollection collection = read(SCHEMA);
+        for (int i = 0; i < 3; i++) {
+            walk(collection);
+            assertEquals(1, namedUnion(collection).getBaseTypes().size());
+            assertEquals(2, 
namedUnion(collection).getMemberTypesQNames().length);
+        }
+    }
+
+    @Test
+    public void testOneWalkLeavesAnonymousUnionMembersUnchanged() {
+        XmlSchemaCollection collection = read(SCHEMA);
+        walk(collection);
+        XmlSchemaSimpleTypeUnion union = (XmlSchemaSimpleTypeUnion)collection
+            .getAttributeByQName(new QName(NS, 
"a")).getSchemaType().getContent();
+        assertEquals(0, union.getBaseTypes().size());
+        assertEquals(2, union.getMemberTypesQNames().length);
+    }
+
+    @Test
+    public void testSchemaWrittenAfterAWalkReadsBackTheSame() throws Exception 
{
+        XmlSchemaCollection collection = read(SCHEMA);
+        walk(collection);
+        walk(collection);
+        StringWriter out = new StringWriter();
+        for (XmlSchema schema : collection.getXmlSchema(null)) {
+            if (NS.equals(schema.getTargetNamespace())) {
+                schema.write(out);
+            }
+        }
+        XmlSchemaSimpleTypeUnion reread = namedUnion(read(out.toString()));
+        assertEquals(1, reread.getBaseTypes().size());
+        assertEquals(2, reread.getMemberTypesQNames().length);
+    }
+
+    private static XmlSchemaCollection read(String schema) {
+        XmlSchemaCollection collection = new XmlSchemaCollection();
+        collection.read(new StringReader(schema));
+        return collection;
+    }
+
+    private static void walk(XmlSchemaCollection collection) {
+        XmlSchemaElement root = collection.getElementByQName(new QName(NS, 
"root"));
+        assertNotNull(root);
+        new XmlSchemaWalker(collection).walk(root);
+    }
+
+    private static XmlSchemaSimpleTypeUnion namedUnion(XmlSchemaCollection 
collection) {
+        XmlSchemaSimpleType type = 
(XmlSchemaSimpleType)collection.getTypeByQName(new QName(NS, "U"));
+        return (XmlSchemaSimpleTypeUnion)type.getContent();
+    }
+}

Reply via email to