in src/main/java/org/apache/xmlbeans/impl/schema/StscComplexTypeResolver.java [805:1000]
static void translateAttributeModel(XmlObject parseTree,
String targetNamespace, boolean chameleon, String formDefault,
List<SchemaType> anonymousTypes, SchemaType outerType,
Set<QName> seenAttributes, SchemaAttributeModelImpl result,
SchemaType baseType, boolean extension,
SchemaAttributeGroupImpl redefinitionFor) {
StscState state = StscState.get();
if (seenAttributes == null) {
seenAttributes = new HashSet<>();
}
boolean seenWildcard = false;
boolean seenRedefinition = false;
SchemaAttributeModel baseModel = null;
if (baseType != null) {
baseModel = baseType.getAttributeModel();
}
try (XmlCursor cur = parseTree.newCursor()) {
for (boolean more = cur.toFirstChild(); more; more = cur.toNextSibling()) {
switch (translateAttributeCode(cur.getName())) {
case ATTRIBUTE_CODE: {
Attribute xsdattr = (Attribute) cur.getObject();
SchemaLocalAttribute sAttr = StscTranslator.translateAttribute(xsdattr, targetNamespace, formDefault, chameleon, anonymousTypes, outerType, baseModel, true);
if (sAttr == null) {
continue;
}
if (seenAttributes.contains(sAttr.getName())) {
state.error(XmlErrorCodes.COMPLEX_TYPE_PROPERTIES$DUPLICATE_ATTRIBUTE,
new Object[]{QNameHelper.pretty(sAttr.getName()), QNameHelper.pretty(outerType.getName())},
xsdattr.xgetName());
continue; // ignore the duplicate attr
}
seenAttributes.add(sAttr.getName());
if (baseModel != null) {
SchemaLocalAttribute baseAttr = baseModel.getAttribute(sAttr.getName());
if (baseAttr == null) {
if (!extension) {
if (!baseModel.getWildcardSet().contains(sAttr.getName())) {
state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ATTR_IN_BASE_WILDCARD_SET,
new Object[]{QNameHelper.pretty(sAttr.getName()), QNameHelper.pretty(outerType.getName())}, xsdattr);
}
}
} else {
if (extension) {
// KHK: cos-ct-extends.1.2?
if (sAttr.getUse() == SchemaLocalAttribute.PROHIBITED) {
state.error("An extension cannot prohibit an attribute from the base type; use restriction instead.", XmlErrorCodes.DUPLICATE_ATTRIBUTE_NAME, xsdattr.xgetUse());
}
} else {
if (sAttr.getUse() != SchemaLocalAttribute.REQUIRED) {
if (baseAttr.getUse() == SchemaLocalAttribute.REQUIRED) {
state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ATTR_REQUIRED,
new Object[]{QNameHelper.pretty(sAttr.getName()), QNameHelper.pretty(outerType.getName())}, xsdattr);
}
if (sAttr.getUse() == SchemaLocalAttribute.PROHIBITED) {
result.removeProhibitedAttribute(sAttr.getName());
}
}
}
}
}
if (sAttr.getUse() != SchemaLocalAttribute.PROHIBITED) {
result.addAttribute(sAttr);
} else {
// attribute is prohibited. If it has an anonymous type remove
// it from the list (this will prevent inclusion of any anonymous
// types defined within the prohibited attribute which would
// otherwise attempt to refer to the prohibited attribute at
// save() time)
SchemaType attrType = sAttr.getType();
if (anonymousTypes != null) {
anonymousTypes.remove(attrType);
}
}
if (sAttr.getDefaultText() != null && !sAttr.isFixed()) {
if (sAttr.getUse() != SchemaLocalAttribute.OPTIONAL) {
state.error(XmlErrorCodes.SCHEMA_ATTR$DEFAULT_AND_USE_OPTIONAL,
new Object[]{QNameHelper.pretty(sAttr.getName())}, xsdattr);
}
}
break;
}
case ANY_ATTRIBUTE_CODE: {
Wildcard xsdwc = (Wildcard) cur.getObject();
if (seenWildcard) {
// KHK: ?
state.error("Only one attribute wildcard allowed", XmlErrorCodes.DUPLICATE_ANY_ATTRIBUTE, xsdwc);
continue; // ignore the extra wildcard
}
seenWildcard = true;
NamespaceList nsList = xsdwc.xgetNamespace();
String nsText;
if (nsList == null) {
nsText = "##any";
} else {
nsText = nsList.getStringValue();
}
QNameSet wcset = QNameSet.forWildcardNamespaceString(nsText, targetNamespace);
if (baseModel != null && !extension) {
if (baseModel.getWildcardSet() == null) {
state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$BASE_HAS_ATTR_WILDCARD, null, xsdwc);
continue; // ignore the extra wildcard
} else if (!baseModel.getWildcardSet().containsAll(wcset)) {
state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ATTR_WILDCARD_SUBSET,
new Object[]{nsText}, xsdwc);
continue; // ignore the restriction
}
}
int wcprocess = translateWildcardProcess(xsdwc.xgetProcessContents());
if (result.getWildcardProcess() == SchemaAttributeModel.NONE) {
result.setWildcardSet(wcset);
result.setWildcardProcess(wcprocess);
} else {
if (extension) {
result.setWildcardSet(wcset.union(result.getWildcardSet()));
result.setWildcardProcess(wcprocess);
} else {
result.setWildcardSet(wcset.intersect(result.getWildcardSet()));
// keep old process
}
}
break;
}
case ATTRIBUTE_GROUP_CODE: {
AttributeGroupRef xsdag = (AttributeGroupRef) cur.getObject();
QName ref = xsdag.getRef();
if (ref == null) {
// KHK: s4s
state.error("Attribute group reference must have a ref attribute", XmlErrorCodes.ATTRIBUTE_GROUP_MISSING_REF, xsdag);
continue;
}
SchemaAttributeGroupImpl group;
if (redefinitionFor != null) {
group = state.findRedefinedAttributeGroup(ref, chameleon ? targetNamespace : null, redefinitionFor);
if (group != null &&
redefinitionFor.getName().equals(group.getName())) {
if (seenRedefinition) {
state.error(XmlErrorCodes.SCHEMA_REDEFINE$ATTR_GROUP_SELF_REF,
new Object[]{QNameHelper.pretty(redefinitionFor.getName())}, xsdag);
}
seenRedefinition = true;
}
} else {
group = state.findAttributeGroup(ref, chameleon ? targetNamespace : null, targetNamespace);
}
if (group == null) {
state.notFoundError(ref, SchemaType.ATTRIBUTE_GROUP, xsdag.xgetRef(), true);
continue;
}
if (state.isProcessing(group)) {
state.error(XmlErrorCodes.SCHEMA_ATTR_GROUP$SELF_REF,
new Object[]{QNameHelper.pretty(group.getName())}, group.getParseObject());
continue;
}
String subTargetNamespace = targetNamespace;
if (group.getTargetNamespace() != null) {
subTargetNamespace = group.getTargetNamespace();
chameleon = group.getChameleonNamespace() != null;
}
state.startProcessing(group);
SchemaAttributeGroupImpl nestedRedefinitionFor = null;
if (group.isRedefinition()) {
nestedRedefinitionFor = group;
}
translateAttributeModel(group.getParseObject(), subTargetNamespace, chameleon,
group.getFormDefault(),
anonymousTypes, outerType, seenAttributes, result, baseType,
extension, nestedRedefinitionFor);
state.finishProcessing(group);
break;
}
default:
// skip things that are not part of the attribute model.
break;
}
}
}
// If this is restriction and no wildcard was present, then
// we have to erase the inherited wildcards
if (!extension && !seenWildcard) {
result.setWildcardSet(null);
result.setWildcardProcess(SchemaAttributeModel.NONE);
}
}