private AttributeDescriptor createAttributeDescriptor( final XSDElementDeclaration elemDecl, int minOccurs, int maxOccurs, CoordinateReferenceSystem crs) { String targetNamespace = elemDecl.getTargetNamespace(); String name = elemDecl.getName(); Name elemName = Types.typeName(targetNamespace, name); AttributeType type = getTypeOf(elemDecl, crs); boolean nillable = elemDecl.isNillable(); Object defaultValue = null; AttributeDescriptor descriptor = createAttributeDescriptor( type, crs, elemName, minOccurs, maxOccurs, nillable, defaultValue); descriptor.getUserData().put(XSDElementDeclaration.class, elemDecl); return descriptor; }
/** * If the type of elemDecl is annonymous creates a new type with the same name than the atrribute * and returns it. If it is not anonymous, looks it up on the registry and in case the type does * not exists in the registry uses a proxy. * * @param elemDecl * @return */ private AttributeType getTypeOf(XSDElementDeclaration elemDecl, CoordinateReferenceSystem crs) { XSDTypeDefinition typeDefinition; // TODO REVISIT, I'm not sure this is the way to find out if the // element's type is defined in line (an thus no need to register it // as a global type) if (elemDecl.isElementDeclarationReference()) { elemDecl = elemDecl.getResolvedElementDeclaration(); } boolean hasToBeRegistered = false; typeDefinition = elemDecl.getAnonymousTypeDefinition(); if (typeDefinition == null) { // anonymous types already has type definition inline in the element // so the handling is different hasToBeRegistered = true; typeDefinition = elemDecl.getTypeDefinition(); } if (typeDefinition == null) { // last resort.. look in the lazy schemas QName qname = Types.toQName(Types.typeName(elemDecl.getTargetNamespace(), elemDecl.getName())); for (SchemaIndex schemaIndex : schemas) { elemDecl = schemaIndex.getElementDeclaration(qname); if (elemDecl != null) { break; } } if (elemDecl != null) { if (elemDecl.isElementDeclarationReference()) { elemDecl = elemDecl.getResolvedElementDeclaration(); } typeDefinition = elemDecl.getAnonymousTypeDefinition(); if (typeDefinition == null) { typeDefinition = elemDecl.getTypeDefinition(); } } } if (typeDefinition == null) { String msg = "The element declaration " + elemDecl.getTargetNamespace() + "#" + elemDecl.getName() + " has a null type definition, can't continue, fix it on the schema"; LOGGER.warning(msg); throw new NoSuchElementException(msg); } AttributeType type; if (hasToBeRegistered) { String targetNamespace = typeDefinition.getTargetNamespace(); String name = typeDefinition.getName(); Name typeName = Types.typeName(targetNamespace, name); type = getAttributeType(typeName, typeDefinition, crs); if (type == null) { type = createType(typeName, typeDefinition, crs, false); } } else { String name = elemDecl.getName(); String targetNamespace = elemDecl.getTargetNamespace(); Name overrideName = Types.typeName(targetNamespace, name); type = createType(overrideName, typeDefinition, crs, true); } return type; }
private void setSubstitutionGroup( XSDComplexTypeDefinition container, XSDElementDeclaration elemDecl, PropertyDescriptor descriptor, CoordinateReferenceSystem crs) { if (descriptor.getUserData().get("substitutionGroup") != null) { // this has been done before return; } List<AttributeDescriptor> substitutionGroup = new ArrayList<AttributeDescriptor>(); descriptor.getUserData().put("substitutionGroup", substitutionGroup); 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) { setSubstitutionGroup((XSDComplexTypeDefinition) typeDef, element, childDesc, crs); } } } } } }