System.Runtime.Serialization.XsdDataContractImporter.ImportComplexType C# (CSharp) Method

ImportComplexType() private method

private ImportComplexType ( CodeTypeDeclaration td, XmlSchemaSet schemas, XmlSchemaComplexType type, XmlQualifiedName qname ) : bool
td System.CodeDom.CodeTypeDeclaration
schemas System.Xml.Schema.XmlSchemaSet
type System.Xml.Schema.XmlSchemaComplexType
qname System.Xml.XmlQualifiedName
return bool
		bool ImportComplexType (CodeTypeDeclaration td, XmlSchemaSet schemas, XmlSchemaComplexType type, XmlQualifiedName qname)
		{
			foreach (XmlSchemaAttribute att in type.AttributeUses.Values)
				if (att.Use != XmlSchemaUse.Optional || att.QualifiedName.Namespace != KnownTypeCollection.MSSimpleNamespace)
					throw new InvalidDataContractException (String.Format ("attribute in DataContract complex type '{0}' is limited to those in {1} namespace, and optional.", qname, KnownTypeCollection.MSSimpleNamespace));

			CodeTypeReference baseClrType = null;
			var particle = type.Particle;
			if (type.ContentModel != null) {
				var xsscr = type.ContentModel.Content as XmlSchemaSimpleContentRestriction;
				if (xsscr != null) {
					if (xsscr.BaseType != null)
						Import (schemas, xsscr.BaseType);
					else
						Import (schemas, xsscr.BaseTypeName);
					// The above will result in an error, but make sure to show we don't support it.
					throw new InvalidDataContractException (String.Format ("complex type simple content restriction is not supported in DataContract (type '{0}')", qname));
				}
				var xscce = type.ContentModel.Content as XmlSchemaComplexContentExtension;
				if (xscce != null) {
					Import (schemas, xscce.BaseTypeName);
					baseClrType = GetCodeTypeReferenceInternal (xscce.BaseTypeName, false);
					if (baseClrType != null)
						td.BaseTypes.Add (baseClrType);

					var baseInfo = GetTypeInfo (xscce.BaseTypeName, false);
					if (baseInfo != null)
						baseInfo.KnownClrTypes.Add (imported_types.First (it => it.XsdType == type).ClrType);
					particle = xscce.Particle;
				}
				var xsccr = type.ContentModel.Content as XmlSchemaComplexContentRestriction;
				if (xsccr != null)
					throw new InvalidDataContractException (String.Format ("complex content type (for type '{0}') has a restriction content model, which is not supported in DataContract.", qname));
			}

			var seq = particle as XmlSchemaSequence;
			if (seq == null && particle != null)
				throw new InvalidDataContractException (String.Format ("Not supported particle {1}. In DataContract, only sequence particle is allowed as the top-level content of a complex type (type '{0}')", qname, particle));

			if (seq != null) {

			foreach (var child in seq.Items)
				if (!(child is XmlSchemaElement))
					throw new InvalidDataContractException (String.Format ("Only local element is allowed as the content of the sequence of the top-level content of a complex type '{0}'. Other particles (sequence, choice, all, any, group ref) are not supported.", qname));

			bool isDictionary = false;
			if (type.Annotation != null) {
				foreach (var ann in type.Annotation.Items) {
					var ai = ann as XmlSchemaAppInfo;
					if (ai != null && ai.Markup != null &&
					    ai.Markup.Length > 0 &&
					    ai.Markup [0].NodeType == XmlNodeType.Element &&
					    ai.Markup [0].LocalName == "IsDictionary" &&
					    ai.Markup [0].NamespaceURI == KnownTypeCollection.MSSimpleNamespace)
						isDictionary = true;
				}
			}

			if (seq.Items.Count == 1) {
				var xe = (XmlSchemaElement) seq.Items [0];
				if (xe.MaxOccursString == "unbounded") {
					// import as a collection contract.
					if (isDictionary) {
						var kvt = xe.ElementSchemaType as XmlSchemaComplexType;
						var seq2 = kvt != null ? kvt.Particle as XmlSchemaSequence : null;
						var k = seq2 != null && seq2.Items.Count == 2 ? seq2.Items [0] as XmlSchemaElement : null;
						var v = seq2 != null && seq2.Items.Count == 2 ? seq2.Items [1] as XmlSchemaElement : null;
						if (k == null || v == null)
							throw new InvalidDataContractException (String.Format ("Invalid Dictionary contract type '{0}'. A Dictionary schema type must have a sequence particle which contains exactly two schema elements for key and value.", type.QualifiedName));
						Import (schemas, k.ElementSchemaType);
						Import (schemas, v.ElementSchemaType);
						td.BaseTypes.Add (new CodeTypeReference ("System.Collections.Generic.Dictionary", GetCodeTypeReference (k.ElementSchemaType.QualifiedName), GetCodeTypeReference (v.ElementSchemaType.QualifiedName)));
						AddTypeAttributes (td, type, xe, k, v);
						return true;
					} else if (type.QualifiedName.Namespace == KnownTypeCollection.MSArraysNamespace &&
						   IsPredefinedType (xe.ElementSchemaType.QualifiedName)) {
						// then this CodeTypeDeclaration is to be removed, and CodeTypeReference to this type should be an array instead.
						var cti = imported_types.First (i => i.XsdType == type);
						cti.ClrType = new CodeTypeReference (GetCodeTypeReference (xe.ElementSchemaType.QualifiedName), 1);
					
						return false;
					}
					else
						Import (schemas, xe.ElementSchemaType);
					td.BaseTypes.Add (new CodeTypeReference ("System.Collections.Generic.List", GetCodeTypeReference (xe.ElementSchemaType.QualifiedName)));
					AddTypeAttributes (td, type, xe);
					return true;
				}
			}
			if (isDictionary)
				throw new InvalidDataContractException (String.Format ("complex type '{0}' is an invalid Dictionary type definition. A Dictionary must have a sequence particle with exactly two child elements", qname));

			// import as a (normal) contract.
			var elems = new List<XmlSchemaElement> ();
			foreach (XmlSchemaElement xe in seq.Items) {
				if (xe.MaxOccurs != 1)
					throw new InvalidDataContractException (String.Format ("schema complex type '{0}' has a content sequence containing an element '{1}' with 'maxOccurs' value as more than 1, which is not supported in DataContract.", qname, xe.QualifiedName));

				if (elems.Any (e => e.QualifiedName.Name == xe.QualifiedName.Name))
					throw new InvalidDataContractException (String.Format ("In schema type '{0}', there already is an element whose name is {1}, where duplicate of element names are not supported.", qname, xe.QualifiedName.Name));

				elems.Add (xe);
			}
			foreach (var xe in elems) {
				// import property type in prior.
				Import (schemas, xe.ElementSchemaType.QualifiedName);
				AddProperty (td, xe);
			}

			} // if (seq != 0)

			AddTypeAttributes (td, type);
			AddExtensionData (td);

			return true;
		}