You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2026/09/17 08:36:31 UTC
(ws-xmlschema) branch coheigea/unresolvable created (now b8210e77)
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a change to branch coheigea/unresolvable
in repository https://gitbox.apache.org/repos/asf/ws-xmlschema.git
at b8210e77 Report unresolvable and complex-where-simple type references as XmlSchemaException
This branch includes the following new commits:
new b8210e77 Report unresolvable and complex-where-simple type references as XmlSchemaException
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(ws-xmlschema) 01/01: Report unresolvable and complex-where-simple type references as XmlSchemaException
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch coheigea/unresolvable
in repository https://gitbox.apache.org/repos/asf/ws-xmlschema.git
commit b8210e775c53059eecad92935de4a67eef7dc042
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Thu Sep 17 09:36:11 2026 +0100
Report unresolvable and complex-where-simple type references as XmlSchemaException
---
.../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>");
+ }
+}