/// <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();
        }
Example #2
0
        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);
        }
Example #3
0
        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;
        }