/** * Return the base type from which this type inherits - that is, all xsd types are either * xsd:anyType or xsd:anySimpleType at the topmost level of inheritance, so return the second * topmost level of type's inheritance. The first specific type from which type inherits. * * @param type * @return the root type definition */ public static XSDTypeDefinition getRootType(XSDTypeDefinition type) { if (type == null) return null; XSDTypeDefinition baseType = type.getBaseType(); while (baseType != null && !XSDConstants.isAnySimpleType(baseType) && !XSDConstants.isAnyType(baseType)) { // walk one more step up the hierarchy type = baseType; baseType = type.getBaseType(); } // Since baseType, type's immediate parent, broke the while condition, we know that type is now // as high up the tree as we want to be return type; }
/** * Creates an {@link AttributeType} that matches the xsd type definition as much as possible. * * <p>The original type definition given by the {@link XSDTypeDefinition} is kept as * AttributeType's metadata stored as a "user data" property using <code>XSDTypeDefinition.class * </code> as key. * * <p>If it is a complex attribute, it will contain all the properties declared in the <code> * typeDefinition</code>, as well as all the properties declared in its super types. TODO: handle * the case where the extension mechanism is restriction. * * @param assignedName * @param typeDefinition * @return */ private AttributeType createType( final Name assignedName, final XSDTypeDefinition typeDefinition, CoordinateReferenceSystem crs, boolean anonymous) { AttributeType attType; // ///////// if (processingTypes.contains(assignedName)) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Recursion found for type " + assignedName + ". Proxying it."); } attType = createProxiedType( assignedName, typeDefinition, anonymous ? anonTypeRegistry : typeRegistry); return attType; } processingTypes.push(assignedName); // ////////// final XSDTypeDefinition baseType = typeDefinition.getBaseType(); AttributeType superType = null; if (baseType != null) { String targetNamespace = baseType.getTargetNamespace(); String name = baseType.getName(); if (name != null) { Name baseTypeName = new NameImpl(targetNamespace, name); superType = getAttributeType(baseTypeName, baseType, crs); } } else { LOGGER.warning(assignedName + " has no super type"); } if (typeDefinition instanceof XSDComplexTypeDefinition) { XSDComplexTypeDefinition complexTypeDef; complexTypeDef = (XSDComplexTypeDefinition) typeDefinition; boolean includeParents = true; List<XSDElementDeclaration> children = Schemas.getChildElementDeclarations(typeDefinition, includeParents); final Collection<PropertyDescriptor> schema = new ArrayList<PropertyDescriptor>(children.size()); XSDElementDeclaration childDecl; AttributeDescriptor descriptor; for (Iterator it = children.iterator(); it.hasNext(); ) { childDecl = (XSDElementDeclaration) it.next(); try { descriptor = createAttributeDescriptor(complexTypeDef, childDecl, crs); } catch (NoSuchElementException e) { String msg = "Failed to create descriptor for '" + childDecl.getTargetNamespace() + "#" + childDecl.getName() + " from container '" + typeDefinition.getTargetNamespace() + "#" + typeDefinition.getName() + "'"; NoSuchElementException nse = new NoSuchElementException(msg); nse.initCause(e); throw nse; } schema.add(descriptor); } if (includeAttributes) { for (XSDAttributeUse attgcontent : complexTypeDef.getAttributeUses()) { XSDAttributeDeclaration att = attgcontent.getContent(); descriptor = createAttributeDescriptor( getXmlAttributeType(), null, new NameImpl(null, "@" + att.getName()), 0, 1, false, null); schema.add(descriptor); } } // set substitution group for descriptors here for (XSDElementDeclaration elemDecl : children) { if (elemDecl.isElementDeclarationReference()) { elemDecl = elemDecl.getResolvedElementDeclaration(); } PropertyDescriptor att = null; for (PropertyDescriptor desc : schema) { if (desc.getName().getLocalPart().equals(elemDecl.getName()) && desc.getName().getNamespaceURI().equals(elemDecl.getTargetNamespace())) { att = desc; break; } } setSubstitutionGroup(complexTypeDef, elemDecl, att, crs); } attType = createComplexAttributeType(assignedName, schema, complexTypeDef, superType); } else { Class<?> binding = String.class; boolean isIdentifiable = false; boolean isAbstract = false; List<Filter> restrictions = Collections.emptyList(); InternationalString description = null; attType = typeFactory.createAttributeType( assignedName, binding, isIdentifiable, isAbstract, restrictions, superType, description); } attType.getUserData().put(XSDTypeDefinition.class, typeDefinition); processingTypes.pop(); // even if the type is anonymous, it still has to be registered somewhere because // it's needed for the proxied types to find them. That's why we have 2 registries, // typeRegistry // and anonTypeRegistry. TypeRegistry is the global one, since anonymous types are meant to // be // local and shouldn't be searchable. register(attType, anonymous); return attType; }