int minOccurs = Schemas.getMinOccurs(container, elemDecl);
int maxOccurs = Schemas.getMaxOccurs(container, elemDecl);
boolean nillable = elemDecl.isNillable();
Iterator substitutions = elemDecl.getSubstitutionGroup().iterator();
XSDElementDeclaration sub;
while (substitutions.hasNext()) {
sub = (XSDElementDeclaration) substitutions.next();
if (!(sub.getName().equals(elemDecl.getName()))
|| !(sub.getTargetNamespace().equals(elemDecl.getTargetNamespace()))) {
Name elemName = Types.typeName(sub.getTargetNamespace(), sub.getName());
AttributeType type = getTypeOf(sub, crs);
if (type != null) {
substitutionGroup.add(createAttributeDescriptor(type, crs, elemName, minOccurs,
maxOccurs, nillable, null));
}
}
}
XSDTypeDefinition typeDef = elemDecl.getType();
if (typeDef instanceof XSDComplexTypeDefinition) {
Name typeName = Types.typeName(typeDef.getTargetNamespace(), typeDef.getName());
AttributeType attType = typeRegistry.get(typeName);
if (!processingTypes.contains(typeName)) {
// ignore processingTypes to avoid endless recursion
if (attType == null || attType instanceof AbstractLazyComplexTypeImpl) {
// type is not yet registered or it's a lazy type from foundation types
// recreate lazy type to ensure everything is loaded
// it will eventually call this method so substitution groups will be set then
LOGGER.finest("Creating attribute type " + typeName);
createType(typeName, typeDef, crs, false);
LOGGER.finest("Registering attribute type " + typeName);
} else if (attType instanceof ComplexType) {
// ensure substitution groups are set for children including non lazy foundation
// types
ComplexType complexType = (ComplexType) attType;
Collection<PropertyDescriptor> children = complexType.getDescriptors();
List<XSDParticle> childParticles = Schemas.getChildElementParticles(typeDef,
true);
for (XSDParticle particle : childParticles) {
XSDElementDeclaration element = (XSDElementDeclaration) particle
.getContent();
if (element.isElementDeclarationReference()) {
element = element.getResolvedElementDeclaration();
}
PropertyDescriptor childDesc = null;
for (PropertyDescriptor desc : children) {
if (desc.getName().getLocalPart().equals(element.getName())
&& desc.getName().getNamespaceURI()
.equals(element.getTargetNamespace())) {
childDesc = desc;
break;
}
}
if (childDesc != null) {