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>");
+ }
+}