private SoalType ImportPhase4ComplexType(Struct st, XElement elem) { if (st == null) { this.Importer.Diagnostics.AddError("Type is missing for the element.", this.Uri, this.GetTextSpan(elem)); return null; } string name = st.Name; XElement complexContentElem = elem.Element(xsd + "complexContent"); XElement simpleContentElem = elem.Element(xsd + "simpleContent"); if (complexContentElem != null) { XElement restrictionElem = complexContentElem.Element(xsd + "restriction"); XElement extensionElem = complexContentElem.Element(xsd + "extension"); if (restrictionElem != null) { return st; } else if (extensionElem != null) { XAttribute baseRef = extensionElem.Attribute("base"); if (baseRef != null) { XName baseRefName = this.GetXName(extensionElem, baseRef.Value); SoalType type = this.Importer.ResolveXsdType(baseRefName); if (type != null) { elem = extensionElem; } else { return null; } } else { return null; } } else { // nop } } else if (simpleContentElem != null) { XElement restrictionElem = simpleContentElem.Element(xsd + "restriction"); XElement extensionElem = simpleContentElem.Element(xsd + "extension"); if (restrictionElem != null) { return null; } else if (extensionElem != null) { return null; } else { return null; } } XElement sequenceElem = elem.Element(xsd + "sequence"); XElement choiceElem = elem.Element(xsd + "choice"); XElement allElem = elem.Element(xsd + "all"); XElement complexElem = null; if (sequenceElem != null) { complexElem = sequenceElem; } else if (choiceElem != null) { complexElem = choiceElem; st.AddAnnotation(SoalAnnotations.Choice); } else if (allElem != null) { complexElem = allElem; st.AddAnnotation(SoalAnnotations.All); } SoalType rt = this.Importer.ResolveXsdReplacementType(st); if (complexElem != null) { foreach (var child in complexElem.Elements()) { if (child.Name.Namespace == xsd) { if (child.Name.LocalName == "element") { this.ImportPhase4ElementProperty(st, rt, child, false); } } } } foreach (var child in elem.Elements()) { if (child.Name.Namespace == xsd) { if (child.Name.LocalName == "attribute") { this.ImportPhase4ElementProperty(st, rt, child, true); } } } return st; }
private Property ImportPhase4ElementProperty(Struct st, SoalType rt, XElement elem, bool attribute) { XAttribute refAttr = elem.Attribute("ref"); XAttribute nameAttr = elem.Attribute("name"); XAttribute typeAttr = elem.Attribute("type"); bool required = false; XAttribute useAttr = elem.Attribute("use"); if (useAttr != null && useAttr.Value == "required") { required = true; } bool sap = false; ArrayType sapArray = null; string sapName = null; string name = null; SoalType type = null; if (refAttr != null) { XName refName = this.GetXName(elem, refAttr.Value); XElement originalElem = null; if (refName != null) { if (attribute) { originalElem = this.Importer.XsdAttributes.GetX(refName); } else { originalElem = this.Importer.XsdElements.GetX(refName); } } if (originalElem != null) { name = refName.LocalName; if (attribute) { type = this.Importer.XsdAttributes.Get(refName); useAttr = originalElem.Attribute("use"); if (useAttr != null && useAttr.Value == "required") { required = true; } } else { type = this.Importer.XsdElements.Get(refName); } if (type == null) { this.Importer.Diagnostics.AddError("Could not resolve type '" + refAttr.Value + "'.", this.Uri, this.GetTextSpan(refAttr)); return null; } } else { this.Importer.Diagnostics.AddError("Could not resolve the reference.", this.Uri, this.GetTextSpan(refAttr)); return null; } } else { if (nameAttr != null) { name = nameAttr.Value; } if (name == null) { this.Importer.Diagnostics.AddError("The element has no name.", this.Uri, this.GetTextSpan(elem)); return null; } if (typeAttr == null) { XElement simpleType = elem.Element(xsd + "simpleType"); XElement complexType = elem.Element(xsd + "complexType"); string typeName = this.GetUniqueName(name, true); if (simpleType != null) { type = this.ImportPhase1SimpleType(simpleType, typeName, attribute ? XsdTypeKind.Attribute : XsdTypeKind.Element, elem, false); type = this.ImportPhase2SimpleType(type, simpleType); } else if (complexType != null) { type = this.ImportPhase1ComplexType(complexType, typeName, attribute ? XsdTypeKind.Attribute : XsdTypeKind.Element, elem, false); Struct childSt = type as Struct; if (childSt != null) { type = this.ImportPhase2ComplexType(childSt, complexType); childSt = type as Struct; if (childSt != null) { type = this.ImportPhase4ComplexType(childSt, complexType); childSt = type as Struct; if (name == "item" && childSt != null && childSt.HasAnnotation(SoalAnnotations.All) && childSt.Properties.Count == 1) { SoalType innerType = childSt.Properties[0].Type; if (innerType.IsArrayType()) { } else { sap = true; sapName = childSt.Properties[0].Name; sapArray = SoalFactory.Instance.CreateArrayType(); sapArray.InnerType = innerType; //this.Importer.RegisterReplacementType(type, sapArray); this.Importer.RemoveType(type); } } } } } else { this.Importer.Diagnostics.AddError("The element has no type.", this.Uri, this.GetTextSpan(elem)); return null; } } else { XName typeRef = this.GetXName(elem, typeAttr.Value); if (typeRef == null) { this.Importer.Diagnostics.AddError("Invalid type reference: '" + typeAttr.Value + "'", this.Uri, this.GetTextSpan(typeAttr)); return null; } type = this.Importer.XsdTypes.Get(typeRef) as SoalType; if (type == null) { type = this.Importer.ResolveXsdPrimitiveType(typeRef) as SoalType; } if (type == null) { this.Importer.Diagnostics.AddError("Could not resolve type '" + typeAttr.Value + "'.", this.Uri, this.GetTextSpan(typeAttr)); return null; } } } SoalType originalType = type; type = this.Importer.ResolveXsdReplacementType(type); XAttribute nillableAttr = elem.Attribute("nillable"); XAttribute minOccursAttr = elem.Attribute("minOccurs"); XAttribute maxOccursAttr = elem.Attribute("maxOccurs"); bool nillable = false; int minOccurs = 1; int maxOccurs = 1; if (nillableAttr != null) { nillable = nillableAttr.Value == "1" || nillableAttr.Value.ToLower() == "true"; } if (minOccursAttr != null) { if (!int.TryParse(minOccursAttr.Value, out minOccurs)) { minOccurs = 1; } } if (maxOccursAttr != null) { if (maxOccursAttr.Value.ToLower() == "unbounded") { maxOccurs = -1; } else if (!int.TryParse(maxOccursAttr.Value, out maxOccurs)) { maxOccurs = 1; } } if (type is PrimitiveType) { if (nillable && type != SoalInstance.Object && type != SoalInstance.String) { NullableType nullable = SoalFactory.Instance.CreateNullableType(); nullable.InnerType = type; type = nullable; } else if (!nillable && (type == SoalInstance.Object || type == SoalInstance.String)) { NonNullableType nonNull = SoalFactory.Instance.CreateNonNullableType(); nonNull.InnerType = type; type = nonNull; } } else { if (!nillable) { NonNullableType nonNull = SoalFactory.Instance.CreateNonNullableType(); nonNull.InnerType = type; type = nonNull; } } Property prop = SoalFactory.Instance.CreateProperty(); string newName = this.GetNewPropertyName(st, name); prop.Name = newName; if (attribute) { prop.Type = type; Annotation attrAnnot = prop.AddAnnotation(SoalAnnotations.Attribute); if (required) { attrAnnot.SetPropertyValue(SoalAnnotationProperties.Required, true); } if (newName != name) { attrAnnot.SetPropertyValue(SoalAnnotationProperties.Name, name); } } else { if (newName != name) { Annotation elemAnnot = prop.AddAnnotation(SoalAnnotations.Element); elemAnnot.SetPropertyValue(SoalAnnotationProperties.Name, name); } if (rt != null && rt is ArrayType) { if (sap) { ((ArrayType)rt).InnerType = sapArray.InnerType; this.Importer.RegisterReplacementType(type, rt); Annotation arrayAnnot = st.AddAnnotation(SoalAnnotations.Type); arrayAnnot.SetPropertyValue(SoalAnnotationProperties.Wrapped, true); arrayAnnot.SetPropertyValue(SoalAnnotationProperties.Items, sapName); arrayAnnot.SetPropertyValue(SoalAnnotationProperties.Sap, true); } else { if (type.IsArrayType()) { type = originalType; this.Importer.Reference(type); } ((ArrayType)rt).InnerType = type; SoalType coreType = type.GetCoreType(); Annotation arrayAnnot = st.AddAnnotation(SoalAnnotations.Type); arrayAnnot.SetPropertyValue(SoalAnnotationProperties.Wrapped, true); if (coreType is NamedElement && ((NamedElement)coreType).Name != prop.Name) { arrayAnnot.SetPropertyValue(SoalAnnotationProperties.Items, prop.Name); } } prop.Type = rt; } else { if (maxOccurs < 0 || maxOccurs > 1) { ArrayType array = SoalFactory.Instance.CreateArrayType(); array.InnerType = type; type = array; } prop.Type = type; } if (minOccurs == 0 && maxOccurs == 1) { prop.SetAnnotationPropertyValue(SoalAnnotations.Element, SoalAnnotationProperties.Optional, true); } } this.Importer.RegisterOriginalType((ModelObject)prop, originalType); st.Properties.Add(prop); return prop; }