public static object GetValue(AnnotationDesc desc) { foreach (var pair in desc.Attributes) { if (string.Equals(pair.First, "value", StringComparison.InvariantCultureIgnoreCase)) { return pair.Second; } } return null; }
public static Object GetValue(AnnotationDesc desc) { foreach (var pair in desc.Attributes) { if (pair.First.ToLower() == "value") { return(pair.Second); } } return(null); }
/// <summary> /// Resolves the type of the attribute. /// </summary> /// <param name="desc">The desc.</param> /// <param name="engineImportService">The engine import service.</param> /// <returns></returns> public static Type ResolveAttributeType(AnnotationDesc desc, EngineImportService engineImportService) { // CLR attributes use a different notation that Java annotations. Format // the attribute according to CLR conventions. var attributeTypeName = desc.Name; var attributeTypeNameForCLR = (attributeTypeName.EndsWith("Attribute")) ? attributeTypeName : String.Format("{0}Attribute", attributeTypeName); // resolve attribute type try { engineImportService.GetClassLoader(); // Currently unused return(engineImportService.ResolveAnnotation(attributeTypeNameForCLR)); } catch (EngineImportException e) { throw new AttributeException("Failed to resolve @-annotation class: " + e.Message); } }
/// <summary> /// Compiles the attribute. /// </summary> /// <param name="desc">The desc.</param> /// <param name="engineImportService">The engine import service.</param> /// <returns></returns> public static Attribute CompileAnnotation(AnnotationDesc desc, EngineImportService engineImportService) { // CLR attributes use a different notation that Java annotations. Format // the attribute according to CLR conventions. var attributeTypeName = desc.Name; var attributeType = ResolveAttributeType(desc, engineImportService); // Get the magic type for the attribute var attributeMagic = MagicType.GetCachedType(attributeType); if (!attributeMagic.ExtendsType(typeof(Attribute))) { throw new AttributeException(String.Format("Annotation '{0}' does not extends System.Attribute", attributeTypeName)); } // Search for a constructor that matches the constructor parameters var theConstructor = attributeType.GetConstructor(new Type[0]); if (theConstructor == null) { throw new AttributeException("Failed to find constructor for @-annotation class"); } // Create the attribute var attributeInstance = (Attribute)theConstructor.Invoke(null); // Create a collection of properties that have been explicitly set for later var explicitPropertyTable = new HashSet <string>(); // Set properties on the attribute foreach (var attributeValuePair in desc.Attributes) { var propertyName = attributeValuePair.First; // Check the explicitPropertyTable to see if we have already set // this property. If we have, then throw an exception as we do not // allow a property to be set twice (i.e. duplicated) if (explicitPropertyTable.Contains(propertyName)) { throw new AttributeException( "Annotation '" + attributeTypeName + "' has duplicate attribute values for attribute '" + propertyName + "'"); } var magicProperty = attributeMagic.ResolveProperty(propertyName, PropertyResolutionStyle.CASE_SENSITIVE); if (magicProperty == null) { throw new AttributeException( String.Format("Failed to find property {0} in annotation type {1}", propertyName, attributeTypeName)); } var propertyValue = attributeValuePair.Second; if (propertyValue is AnnotationDesc) { propertyValue = CompileAnnotation((AnnotationDesc)propertyValue, engineImportService); } var magicPropertyType = magicProperty.PropertyType; if (magicPropertyType.IsArray) { propertyValue = CheckArray(attributeTypeName, magicProperty, propertyName, propertyValue); } propertyValue = CheckTypeMismatch(attributeTypeName, magicPropertyType, propertyName, propertyValue); magicProperty.SetFunction(attributeInstance, propertyValue); explicitPropertyTable.Add(propertyName); } // Make sure all required attributes were set foreach (var property in attributeMagic.GetSimpleProperties(true)) { #if EXPLICIT_ATTRIBUTE_PROPERTIES // Explicit properties make this relatively painless if the value // was set through the property model. if (explicitPropertyTable.Contains(property.Name)) { continue; } #endif // Not set explicitly which makes this somewhat ... painful if (property.Member is PropertyInfo) { var propertyInfo = (PropertyInfo)property.Member; var requiredAttributes = propertyInfo.GetCustomAttributes(typeof(RequiredAttribute), true); if ((requiredAttributes != null) && (requiredAttributes.Length > 0)) { var defaultValue = GetDefaultValue(property.PropertyType); // Property is required ... unfortunately, properties can be set through // constructors or late-bound properties. It's honestly impossible for us // to accurately determine if we have really bound the property. var currentValue = property.GetMethod.Invoke(attributeInstance, new object[0]); // Here's where it gets fuzzy, we're going to compare the currentValue against // the defaultValue. This is an inexact science ... if (Equals(defaultValue, currentValue)) { var propertyName = property.Name; throw new AttributeException("Annotation '" + attributeTypeName + "' requires a value for attribute '" + propertyName + "'"); } } } } if (attributeInstance is HintAttribute) { HintEnumExtensions.ValidateGetListed(attributeInstance); } return(attributeInstance); }
private static Attribute CreateAttributeInstance( AnnotationDesc desc, ImportServiceCompileTime importService) { // resolve class Type annotationClass; try { annotationClass = importService.ResolveAnnotation(desc.Name); } catch (ImportException e) { throw new AnnotationException("Failed to resolve @-annotation class: " + e.Message); } // obtain Annotation class properties var annotationAttributeLists = GetAttributes(annotationClass); ISet<string> allAttributes = new HashSet<string>(); ISet<string> requiredAttributes = new HashSet<string>(); foreach (var annotationAttribute in annotationAttributeLists) { allAttributes.Add(annotationAttribute.Name); if (annotationAttribute.DefaultValue != null) { requiredAttributes.Add(annotationAttribute.Name); } } // get attribute values IList<string> providedValues = new List<string>(); foreach (var annotationValuePair in desc.Attributes) { providedValues.Add(annotationValuePair.First); } // for all attributes determine value IDictionary<string, object> properties = new Dictionary<string, object>(); foreach (var annotationAttribute in annotationAttributeLists) { // find value pair for this attribute var attributeName = annotationAttribute.Name; Pair<string, object> pairFound = null; foreach (var annotationValuePair in desc.Attributes) { if (annotationValuePair.First.Equals(attributeName)) { pairFound = annotationValuePair; } } var valueProvided = pairFound == null ? null : pairFound.Second; var value = GetFinalValue(annotationClass, annotationAttribute, valueProvided, importService); properties.Put(attributeName, value); providedValues.Remove(attributeName); requiredAttributes.Remove(attributeName); } if (requiredAttributes.Count > 0) { var required = new List<string>(requiredAttributes); required.Sort(); throw new AnnotationException( "Annotation '" + annotationClass.GetSimpleName() + "' requires a value for attribute '" + required[0] + "'"); } if (providedValues.Count > 0) { var provided = new List<string>(providedValues); provided.Sort(); if (allAttributes.Contains(provided[0])) { throw new AnnotationException( "Annotation '" + annotationClass.GetSimpleName() + "' has duplicate attribute values for attribute '" + provided[0] + "'"); } throw new AnnotationException( "Annotation '" + annotationClass.GetSimpleName() + "' does not have an attribute '" + provided[0] + "'"); } // Create a proxy of the attribute return (new EPLAnnotationInvocationHandler(annotationClass, properties)).CreateProxyInstance(); }