/// <summary> /// Constructor for <c>ClassDescriptor</c> takes /// <c>Type</c> as the input parameter. Initializes /// internal variables and resovles the tagName for /// class. /// </summary> /// <param name="thatClass"> /// <c>Type</c> of the class defined by this /// <c>ClassDescriptor</c> /// </param> public ClassDescriptor(Type thatClass) : base(XmlTools.GetXmlTagName(thatClass, SimplTypesScope.STATE), thatClass.Name) { _describedClass = thatClass; _describedClassSimpleName = thatClass.Name; _describedClassPackageName = thatClass.Namespace; //generics if (thatClass.GetTypeInfo().IsGenericType) { int index = _describedClassSimpleName.IndexOf('`'); String simpleName = _describedClassSimpleName.Substring(0, index); name = simpleName; _describedClassSimpleName = simpleName; index = _tagName.IndexOf('`'); if (index != -1) { String tagName = _tagName.Substring(0, index); this._tagName = tagName; } } if (XmlTools.IsAnnotationPresent <SimplUseEqualsEquals>(thatClass)) { _strictObjectGraphRequired = true; } SimplDescriptorClasses descriptorsClassesAttribute = XmlTools.GetAnnotation <SimplDescriptorClasses>(thatClass); if (descriptorsClassesAttribute != null) { classDescriptorClass = descriptorsClassesAttribute.Classes[0]; fieldDescriptorClass = descriptorsClassesAttribute.Classes[1]; } if (XmlTools.IsAnnotationPresent(thatClass, typeof(SimplInherit))) { this.SuperClass = GetClassDescriptor(thatClass.GetTypeInfo().BaseType); } //generics AddGenericTypeVariables(); }
private int DeriveNestedSerialization(FieldInfo thatField, int annotationType) { int result = annotationType; Type thatFieldType = thatField.FieldType; switch (annotationType) { case FieldTypes.CompositeElement: String compositeTag = XmlTools.GetAnnotation <SimplComposite>(thatField).TagName; Boolean isWrap = XmlTools.IsAnnotationPresent <SimplWrap>(thatField); Boolean compositeTagIsNullOrEmpty = String.IsNullOrEmpty(compositeTag); if (!IsPolymorphic) { if (isWrap && compositeTagIsNullOrEmpty) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate [SimplComposite] " + thatField.Name + " because its tag argument is missing."; Debug.WriteLine(msg); return(FieldTypes.IgnoredAttribute); } _elementClassDescriptor = ClassDescriptor.GetClassDescriptor(thatFieldType); _elementClass = _elementClassDescriptor.DescribedClass; compositeTag = XmlTools.GetXmlTagName(thatField); } else { if (!compositeTagIsNullOrEmpty) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate [SimplComposite] " + thatField.Name + " because its tag argument is missing."; Debug.WriteLine(msg); } } compositeTagName = compositeTag; break; case FieldTypes.CollectionElement: if (!(typeof(IList).GetTypeInfo().IsAssignableFrom(thatField.FieldType.GetTypeInfo()))) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate " + "[SimplCollection] " + field.Name + " because the annotated field is not an instance of " + typeof(IList).Name + "."; Debug.WriteLine(msg); return(FieldTypes.IgnoredAttribute); } String collectionTag = XmlTools.GetAnnotation <SimplCollection>(thatField).TagName; if (!IsPolymorphic) { Type collectionElementType = GetTypeArgs(thatField, 0); if (String.IsNullOrEmpty(collectionTag)) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate [SimplCollection]" + field.Name + " because its tag argument is missing."; Debug.WriteLine(msg); return(FieldTypes.IgnoredElement); } if (collectionElementType == null) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate [SimplCollection] " + field.Name + " because the parameterized type argument for the Collection is missing."; Debug.WriteLine(msg); return(FieldTypes.IgnoredElement); } if (!TypeRegistry.ScalarTypes.Contains(collectionElementType)) { _elementClassDescriptor = ClassDescriptor.GetClassDescriptor(collectionElementType); _elementClass = _elementClassDescriptor.DescribedClass; } else { result = FieldTypes.CollectionScalar; DeriveScalarSerialization(collectionElementType, field); if (ScalarType == null) { result = FieldTypes.IgnoredElement; String msg = "Can't identify ScalarType for serialization of " + collectionElementType; Debug.WriteLine(msg); } } } else { if (!String.IsNullOrEmpty(collectionTag)) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tIgnoring argument to [SimplCollection] " + field.Name + " because it is declared polymorphic with [SimplClasses]."; } } _collectionOrMapTagName = collectionTag; collectionType = TypeRegistry.GetCollectionType(thatField); break; case FieldTypes.MapElement: if (!(typeof(IDictionary).GetTypeInfo().IsAssignableFrom(thatField.FieldType.GetTypeInfo()))) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate " + "[SimplMap] " + field.Name + " because the annotated field is not an instance of " + typeof(IDictionary).Name + "."; Debug.WriteLine(msg); return(FieldTypes.IgnoredAttribute); } String mapTag = XmlTools.GetAnnotation <SimplMap>(thatField).TagName; if (!IsPolymorphic) { Type mapElementType = GetTypeArgs(thatField, 1); if (String.IsNullOrEmpty(mapTag)) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate [SimplMap]" + field.Name + " because its tag argument is missing."; Debug.WriteLine(msg); return(FieldTypes.IgnoredElement); } if (mapElementType == null) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate [SimplMap] " + field.Name + " because the parameterized type argument for the map is missing."; Debug.WriteLine(msg); return(FieldTypes.IgnoredElement); } if (!TypeRegistry.ScalarTypes.Contains(mapElementType)) { _elementClassDescriptor = ClassDescriptor.GetClassDescriptor(mapElementType); _elementClass = _elementClassDescriptor.DescribedClass; } } else { if (!String.IsNullOrEmpty(mapTag)) { String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tIgnoring argument to [SimplMap] " + field.Name + " because it is declared polymorphic with [SimplClasses]."; } } _collectionOrMapTagName = mapTag; collectionType = TypeRegistry.GetCollectionType(thatField); break; } switch (annotationType) { case FieldTypes.CollectionElement: case FieldTypes.MapElement: if (!XmlTools.IsAnnotationPresent <SimplNoWrap>(thatField)) { _wrapped = true; } collectionType = TypeRegistry.GetCollectionType(thatField); break; case FieldTypes.CompositeElement: if (XmlTools.IsAnnotationPresent <SimplWrap>(thatField)) { _wrapped = true; } break; } return(result); }
public FieldDescriptor(ClassDescriptor declaringClassDescriptor, FieldInfo field, int annotationType) : base(XmlTools.GetXmlTagName(field), field.Name) { this.declaringClassDescriptor = declaringClassDescriptor; this.field = field; fieldType = field.FieldType.Name; //generics if (field.FieldType.IsGenericParameter || field.FieldType.GetTypeInfo().IsGenericType) { Type realFieldType = field.FieldType; while (realFieldType.IsGenericParameter) { Type[] realFieldTypeConstraints = realFieldType.GetTypeInfo().GetGenericParameterConstraints(); if (realFieldTypeConstraints == null || realFieldTypeConstraints.Length == 0) { realFieldType = typeof(Object); break; } else { realFieldType = realFieldTypeConstraints[0]; } } fieldType = realFieldType.Name; if (realFieldType.GetTypeInfo().IsGenericType)//can also be a generic parameter that extends a generic type { int pos = fieldType.IndexOf('`'); fieldType = fieldType.Substring(0, pos); } } if (XmlTools.IsAnnotationPresent <SimplMapKeyField>(field)) { mapKeyFieldName = XmlTools.GetAnnotation <SimplMapKeyField>(field).FieldName; } DerivePolymorphicDescriptors(field); type = FieldTypes.UnsetType; if (annotationType == FieldTypes.Scalar) { type = DeriveScalarSerialization(field); } else { type = DeriveNestedSerialization(field, annotationType); } String fieldName = field.Name; StringBuilder capFieldName = new StringBuilder(fieldName); //generics Type genericType = field.DeclaringType; isGeneric = genericType.GetTypeInfo().IsGenericType || genericType.IsGenericParameter; }