예제 #1
0
        private static IList<AnnotationAttribute> GetAttributes(Type annotationClass)
        {
            var props = new List<AnnotationAttribute>();

#if true
            var clazzProperties = annotationClass.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            if (clazzProperties.Length == 0) {
                return Collections.GetEmptyList<AnnotationAttribute>();
            }

            foreach (var clazzProperty in clazzProperties
                .Where(c => c.DeclaringType != typeof(Attribute))
                .Where(c => c.CanRead)) {
                var annotationAttribute = new AnnotationAttribute(
                    clazzProperty.Name,
                    clazzProperty.PropertyType,
                    GetDefaultValue(clazzProperty));

                props.Add(annotationAttribute);
            }
#else
            var methods = annotationClass.GetMethods();
            if (methods.Length == 0) {
                return Collections.GetEmptyList<AnnotationAttribute>();
            }

            for (var i = 0; i < methods.Length; i++) {
                var method = methods[i];
                if (method.ReturnType == typeof(void)) {
                    continue;
                }

                var parameters = method.GetParameters();
                if (parameters.Length > 0) {
                    continue;
                }

                var methodName = method.Name;
                if (methodName.Equals("GetType") ||
                    methodName.Equals("ToString") ||
                    methodName.Equals("AnnotationType") ||
                    methodName.Equals("GetHashCode")) {
                    continue;
                }

                props.Add(new AnnotationAttribute(method.Name, method.ReturnType, null)); // TBD: method.DefaultValue
            }
#endif

            props.Sort(
                (
                    o1,
                    o2) => o1.Name.CompareTo(o2.Name));
            return props;
        }
예제 #2
0
        private static object GetFinalValue(
            Type annotationClass,
            AnnotationAttribute annotationAttribute,
            object value,
            ImportServiceCompileTime importService)
        {
            if (value == null) {
                if (annotationAttribute.DefaultValue == null) {
                    throw new AnnotationException(
                        "Annotation '" +
                        annotationClass.GetSimpleName() +
                        "' requires a value for attribute '" +
                        annotationAttribute.Name +
                        "'");
                }

                return annotationAttribute.DefaultValue;
            }

            // handle non-array
            if (!annotationAttribute.AnnotationType.IsArray) {
                // handle primitive value
                if (!annotationAttribute.AnnotationType.IsAttribute()) {
                    // if expecting an enumeration type, allow string value
                    if (annotationAttribute.AnnotationType.IsEnum && (value is string valueString)) {
                        valueString = valueString.Trim();

                        var annotationType = annotationAttribute.AnnotationType;
                        try {
                            return Enum.Parse(annotationType, valueString, true);
                        }
                        catch (ArgumentException) {
                            throw new AnnotationException(
                                "Annotation '" +
                                annotationClass.FullName +
                                "' requires an enum-value '" +
                                annotationAttribute.AnnotationType.FullName +
                                "' for attribute '" +
                                annotationAttribute.Name +
                                "' but received '" +
                                value +
                                "' which is not one of the enum choices");
                        }
                    }

                    // cast as required
                    var caster = SimpleTypeCasterFactory.GetCaster(value.GetType(), annotationAttribute.AnnotationType);
                    var finalValue = caster.Cast(value);
                    if (finalValue == null) {
                        throw new AnnotationException(
                            "Annotation '" +
                            annotationClass.Name +
                            "' requires a " +
                            annotationAttribute.AnnotationType.Name +
                            "-typed value for attribute '" +
                            annotationAttribute.Name +
                            "' but received " +
                            "a " +
                            value.GetType().Name +
                            "-typed value");
                    }

                    return finalValue;
                }

                // nested annotation
                if (!(value is AnnotationDesc)) {
                    throw new AnnotationException(
                        "Annotation '" +
                        annotationClass.GetSimpleName() +
                        "' requires a " +
                        annotationAttribute.AnnotationType.GetSimpleName() +
                        "-typed value for attribute '" +
                        annotationAttribute.Name +
                        "' but received " +
                        "a " +
                        value.GetType().GetSimpleName() +
                        "-typed value");
                }

                return CreateAttributeInstance((AnnotationDesc) value, importService);
            }

            if (!(value is Array valueAsArray)) {
                throw new AnnotationException(
                    "Annotation '" +
                    annotationClass.GetSimpleName() +
                    "' requires a " +
                    annotationAttribute.AnnotationType.GetSimpleName() +
                    "-typed value for attribute '" +
                    annotationAttribute.Name +
                    "' but received " +
                    "a " +
                    value.GetType().GetSimpleName() +
                    "-typed value");
            }

            var componentType = annotationAttribute.AnnotationType.GetElementType();
            var array = Array.CreateInstance(componentType, valueAsArray.Length);

            for (var i = 0; i < valueAsArray.Length; i++) {
                var arrayValue = valueAsArray.GetValue(i);
                if (arrayValue == null) {
                    throw new AnnotationException(
                        "Annotation '" +
                        annotationClass.GetSimpleName() +
                        "' requires a " +
                        "non-null value for array elements for attribute '" +
                        annotationAttribute.Name +
                        "'");
                }

                object finalValue;
                if (arrayValue is AnnotationDesc annotationDesc) {
                    var inner = CreateAttributeInstance(annotationDesc, importService);
                    if (!componentType.IsInstanceOfType(inner)) {
                        throw MakeArrayMismatchException(
                            annotationClass,
                            componentType,
                            annotationAttribute.Name,
                            inner.GetType());
                    }

                    finalValue = inner;
                }
                else {
                    var caster = SimpleTypeCasterFactory.GetCaster(
                        arrayValue.GetType(),
                        annotationAttribute.AnnotationType.GetElementType());
                    finalValue = caster.Cast(arrayValue);
                    if (finalValue == null) {
                        throw MakeArrayMismatchException(
                            annotationClass,
                            componentType,
                            annotationAttribute.Name,
                            arrayValue.GetType());
                    }
                }

                array.SetValue(finalValue, i);
            }

            return array;
        }