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

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


The following commit(s) were added to refs/heads/master by this push:
     new b72abb91 Report unresolvable and complex-where-simple type references 
as XmlSchemaException (#155)
b72abb91 is described below

commit b72abb912b0fce5bf3ec03e218f35e7470c1258d
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Thu Sep 17 09:40:04 2026 +0100

    Report unresolvable and complex-where-simple type references as 
XmlSchemaException (#155)
---
 .../ws/commons/schema/walker/XmlSchemaScope.java   |  52 +++++---
 .../schema/walker/UnresolvableSimpleTypeTest.java  | 144 +++++++++++++++++++++
 2 files changed, 180 insertions(+), 16 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 c05349a5..24cd4dd8 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
@@ -160,6 +160,25 @@ final class XmlSchemaScope {
         return anyAttr;
     }
 
+    /**
+     * Resolves a named type reference that the schema requires to be a simple 
type. A reference
+     * that does not resolve, or resolves to a complex type, is a defect in 
the schema: the core
+     * parser does not check either, so both reach here.
+     */
+    private XmlSchemaSimpleType simpleTypeByName(QName typeName, String role, 
String owner) {
+        final XmlSchemaType type =
+            (typeName == null) ? null : 
schemasByNamespace.getTypeByName(typeName);
+        if (type == null) {
+            throw new XmlSchemaException("The " + role + " " + owner + " (" + 
typeName
+                                         + ") does not resolve to a type in 
this collection.");
+        }
+        if (!(type instanceof XmlSchemaSimpleType)) {
+            throw new XmlSchemaException("The " + role + " " + owner + " (" + 
typeName
+                                         + ") resolves to a complex type; a 
simple type is required.");
+        }
+        return (XmlSchemaSimpleType)type;
+    }
+
     private void walk(XmlSchemaType type) {
         if (type instanceof XmlSchemaSimpleType) {
             walk((XmlSchemaSimpleType)type);
@@ -185,11 +204,8 @@ final class XmlSchemaScope {
             XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)content;
             XmlSchemaSimpleType listType = list.getItemType();
             if (listType == null) {
-                listType = 
(XmlSchemaSimpleType)schemasByNamespace.getTypeByName(list.getItemTypeName());
-            }
-            if (listType == null) {
-                throw new IllegalArgumentException("Unrecognized schema type 
for list "
-                                                   + getName(simpleType, 
"{Anonymous List Type}"));
+                listType = simpleTypeByName(list.getItemTypeName(), "item type 
of list",
+                                            getName(simpleType, "{Anonymous 
List Type}"));
             }
 
             XmlSchemaScope parentScope = getScope(listType);
@@ -199,8 +215,11 @@ final class XmlSchemaScope {
             case ATOMIC:
                 break;
             default:
-                throw new IllegalStateException("Attempted to create a list 
from a "
-                                                + 
parentScope.getTypeInfo().getType() + " type.");
+                throw new XmlSchemaException("The list "
+                                             + getName(simpleType, "{Anonymous 
List Type}")
+                                             + " has an item type of "
+                                             + 
parentScope.getTypeInfo().getType()
+                                             + "; a list item must be atomic 
or a union.");
             }
 
             typeInfo = new XmlSchemaTypeInfo(parentScope.getTypeInfo());
@@ -216,10 +235,8 @@ final class XmlSchemaScope {
                 }
 
                 for (QName namedBaseType : namedBaseTypes) {
-                    XmlSchemaSimpleType baseType = 
(XmlSchemaSimpleType)schemasByNamespace.getTypeByName(namedBaseType);
-                    if (baseType != null) {
-                        baseTypes.add(baseType);
-                    }
+                    baseTypes.add(simpleTypeByName(namedBaseType, "member type 
of union",
+                                                   getName(simpleType, 
"{Anonymous Union Type}")));
                 }
             }
 
@@ -228,8 +245,9 @@ final class XmlSchemaScope {
              * types.
              */
             if ((baseTypes == null) || baseTypes.isEmpty()) {
-                throw new IllegalArgumentException("Unrecognized base types 
for union "
-                                                   + getName(simpleType, 
"{Anonymous Union Type}"));
+                throw new XmlSchemaException("The union "
+                                             + getName(simpleType, "{Anonymous 
Union Type}")
+                                             + " has no member types.");
             }
 
             List<XmlSchemaTypeInfo> childTypes = new 
ArrayList<XmlSchemaTypeInfo>(baseTypes.size());
@@ -260,7 +278,8 @@ final class XmlSchemaScope {
             } else {
                 XmlSchemaSimpleType baseType = restr.getBaseType();
                 if (baseType == null) {
-                    baseType = 
(XmlSchemaSimpleType)schemasByNamespace.getTypeByName(restr.getBaseTypeName());
+                    baseType = simpleTypeByName(restr.getBaseTypeName(), "base 
type of restriction",
+                                                getName(simpleType, 
"{Anonymous Simple Type}"));
                 }
 
                 if (baseType != null) {
@@ -599,7 +618,8 @@ final class XmlSchemaScope {
         if (schemaType == null) {
             final QName typeQName = globalAttr.getSchemaTypeName();
             if (typeQName != null) {
-                schemaType = (XmlSchemaSimpleType) 
schemasByNamespace.getTypeByName(typeQName);
+                schemaType = simpleTypeByName(typeQName, "type of attribute",
+                                              
String.valueOf(globalAttr.getQName()));
             }
         }
 
@@ -850,7 +870,7 @@ final class XmlSchemaScope {
             typeInfo = new XmlSchemaTypeInfo(parentTypeInfo.getBaseType(), 
facets);
             break;
         default:
-            throw new IllegalStateException("Cannot restrict on a " + 
parentTypeInfo.getType() + " type.");
+            throw new XmlSchemaException("Cannot restrict on a " + 
parentTypeInfo.getType() + " type.");
         }
 
         if (parentTypeInfo.getUserRecognizedType() != null) {
diff --git 
a/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/UnresolvableSimpleTypeTest.java
 
b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/UnresolvableSimpleTypeTest.java
new file mode 100644
index 00000000..4d48439b
--- /dev/null
+++ 
b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/UnresolvableSimpleTypeTest.java
@@ -0,0 +1,144 @@
+/**
+ * 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 javax.xml.namespace.QName;
+
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaException;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Where a schema names a type that must be simple, the core parser checks 
neither that the
+ * name resolves nor that what it resolves to is simple, so both reach the 
walker.
+ */
+public class UnresolvableSimpleTypeTest extends Assert {
+
+    private static final String COMPLEX_TYPE =
+        "<xs:complexType name=\"ct\"><xs:sequence/></xs:complexType>";
+
+    private static void walk(String body) {
+        XmlSchemaCollection collection = new XmlSchemaCollection();
+        collection.read(new StringReader(
+            "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"; 
xmlns:t=\"urn:t\""
+            + " targetNamespace=\"urn:t\" elementFormDefault=\"qualified\">"
+            + body + "</xs:schema>"));
+        XmlSchemaElement root = collection.getElementByQName(new 
QName("urn:t", "root"));
+        assertNotNull(root);
+        new XmlSchemaWalker(collection).walk(root);
+    }
+
+    private static void assertRejected(String body, String expectedFragment) {
+        try {
+            walk(body);
+            fail("expected the unusable type reference to be rejected");
+        } catch (XmlSchemaException expected) {
+            assertTrue(expected.getMessage(), 
expected.getMessage().contains(expectedFragment));
+        }
+    }
+
+    @Test
+    public void testListItemTypeThatDoesNotResolve() {
+        assertRejected("<xs:simpleType name=\"l\"><xs:list 
itemType=\"t:missing\"/></xs:simpleType>"
+                       + "<xs:element name=\"root\" type=\"t:l\"/>",
+                       "does not resolve");
+    }
+
+    @Test
+    public void testListItemTypeThatIsComplex() {
+        assertRejected(COMPLEX_TYPE
+                       + "<xs:simpleType name=\"l\"><xs:list 
itemType=\"t:ct\"/></xs:simpleType>"
+                       + "<xs:element name=\"root\" type=\"t:l\"/>",
+                       "complex type");
+    }
+
+    @Test
+    public void testListOfListIsRejected() {
+        assertRejected("<xs:simpleType name=\"l1\"><xs:list 
itemType=\"xs:int\"/></xs:simpleType>"
+                       + "<xs:simpleType name=\"l2\"><xs:list 
itemType=\"t:l1\"/></xs:simpleType>"
+                       + "<xs:element name=\"root\" type=\"t:l2\"/>",
+                       "atomic or a union");
+    }
+
+    @Test
+    public void testUnionMemberThatDoesNotResolve() {
+        assertRejected("<xs:simpleType name=\"u\"><xs:union 
memberTypes=\"t:missing\"/></xs:simpleType>"
+                       + "<xs:element name=\"root\" type=\"t:u\"/>",
+                       "does not resolve");
+    }
+
+    @Test
+    public void testUnionMemberThatIsComplex() {
+        assertRejected(COMPLEX_TYPE
+                       + "<xs:simpleType name=\"u\"><xs:union 
memberTypes=\"xs:int t:ct\"/></xs:simpleType>"
+                       + "<xs:element name=\"root\" type=\"t:u\"/>",
+                       "complex type");
+    }
+
+    @Test
+    public void testRestrictionBaseThatDoesNotResolve() {
+        assertRejected("<xs:simpleType name=\"s\"><xs:restriction 
base=\"t:missing\"/></xs:simpleType>"
+                       + "<xs:element name=\"root\" type=\"t:s\"/>",
+                       "does not resolve");
+    }
+
+    @Test
+    public void testRestrictionBaseThatIsComplex() {
+        assertRejected(COMPLEX_TYPE
+                       + "<xs:simpleType name=\"s\"><xs:restriction 
base=\"t:ct\"/></xs:simpleType>"
+                       + "<xs:element name=\"root\" type=\"t:s\"/>",
+                       "complex type");
+    }
+
+    @Test
+    public void testAttributeTypedByAComplexType() {
+        assertRejected(COMPLEX_TYPE
+                       + "<xs:element name=\"root\"><xs:complexType>"
+                       + "<xs:attribute name=\"a\" 
type=\"t:ct\"/></xs:complexType></xs:element>",
+                       "complex type");
+    }
+
+    @Test
+    public void testSimpleContentRestrictionOfAComplexBase() {
+        assertRejected("<xs:complexType name=\"b\"><xs:complexContent>"
+                       + "<xs:restriction 
base=\"xs:anyType\"><xs:sequence/></xs:restriction>"
+                       + "</xs:complexContent></xs:complexType>"
+                       + "<xs:complexType name=\"ct2\"><xs:simpleContent>"
+                       + "<xs:restriction 
base=\"t:b\"/></xs:simpleContent></xs:complexType>"
+                       + "<xs:element name=\"root\" type=\"t:ct2\"/>",
+                       "Cannot restrict");
+    }
+
+    @Test
+    public void testWellFormedSimpleTypesStillWalk() {
+        walk("<xs:simpleType name=\"u\"><xs:union memberTypes=\"xs:int 
xs:string\"/></xs:simpleType>"
+             + "<xs:simpleType name=\"l\"><xs:list 
itemType=\"t:u\"/></xs:simpleType>"
+             + "<xs:simpleType name=\"r\"><xs:restriction base=\"xs:string\">"
+             + "<xs:maxLength value=\"8\"/></xs:restriction></xs:simpleType>"
+             + "<xs:element name=\"root\"><xs:complexType><xs:sequence>"
+             + "<xs:element name=\"a\" type=\"t:l\"/><xs:element name=\"b\" 
type=\"t:r\"/>"
+             + "</xs:sequence><xs:attribute name=\"c\" 
type=\"t:u\"/></xs:complexType></xs:element>");
+    }
+}

Reply via email to