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; }
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; }