/// <summary> /// Get the Enum value from the record using the given property name. /// </summary> /// <typeparam name="T">The output enum type.</typeparam> /// <param name="record">The record expression.</param> /// <param name="propertyName">The property name.</param> /// <returns>The Enum value or null.</returns> public static T?GetEnum <T>(this IEdmRecordExpression record, string propertyName) where T : struct { Utils.CheckArgumentNull(record, nameof(record)); Utils.CheckArgumentNull(propertyName, nameof(propertyName)); if (record.Properties != null) { IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName); if (property != null) { IEdmEnumMemberExpression value = property.Value as IEdmEnumMemberExpression; if (value != null && value.EnumMembers != null && value.EnumMembers.Any()) { IEdmEnumMember member = value.EnumMembers.First(); T result; if (Enum.TryParse(member.Name, out result)) { return(result); } } } } return(null); }
private static bool TryCastEnumConstantAsType(IEdmEnumMemberExpression expression, IEdmTypeReference type, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { if (!type.IsEnum()) { discoveredErrors = new EdmError[] { new EdmError( expression.Location(), EdmErrorCode.ExpressionEnumKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionEnumKindNotValidForAssertedType) }; return(false); } foreach (var member in expression.EnumMembers) { if (!TestTypeMatch(member.DeclaringType, type.Definition, expression.Location(), matchExactly, out discoveredErrors)) { return(false); } } discoveredErrors = Enumerable.Empty <EdmError>(); return(true); }
/// <summary> /// Init the <see cref="SearchRestrictionsType"/>. /// </summary> /// <param name="record">The input record.</param> public void Initialize(IEdmRecordExpression record) { Utils.CheckArgumentNull(record, nameof(record)); // Searchable Searchable = record.GetBoolean("Searchable"); // read the "UnsupportedExpressions" IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == "UnsupportedExpressions"); if (property != null) { IEdmEnumMemberExpression value = property.Value as IEdmEnumMemberExpression; if (value != null && value.EnumMembers != null) { SearchExpressions result; foreach (var v in value.EnumMembers) { if (Enum.TryParse(v.Name, out result)) { if (UnsupportedExpressions == null) { UnsupportedExpressions = result; } else { UnsupportedExpressions = UnsupportedExpressions | result; } } } } } }
protected override bool Initialize(IEdmVocabularyAnnotation annotation) { if (annotation == null || annotation.Value == null || annotation.Value.ExpressionKind != EdmExpressionKind.Record) { return(false); } IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value; // Searchable Searchable = record.GetBoolean("Searchable"); // read the "UnsupportedExpressions" IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == "UnsupportedExpressions"); if (property != null) { IEdmEnumMemberExpression value = property.Value as IEdmEnumMemberExpression; if (value != null && value.EnumMembers != null) { SearchExpressions result; foreach (var v in value.EnumMembers) { if (Enum.TryParse(v.Name, out result)) { if (UnsupportedExpressions == null) { UnsupportedExpressions = result; } else { UnsupportedExpressions = UnsupportedExpressions | result; } } } } } return(true); }
protected override void ProcessEnumMemberExpression(IEdmEnumMemberExpression expression) { this.schemaWriter.WriteEnumMemberExpressionElement(expression); }
internal void WriteEnumMemberExpressionElement(IEdmEnumMemberExpression expression) { this.xmlWriter.WriteStartElement(CsdlConstants.Element_EnumMember); this.xmlWriter.WriteString(EnumMemberAsXml(expression.EnumMembers)); this.WriteEndElement(); }
private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context) { switch (expression.ExpressionKind) { case EdmExpressionKind.IntegerConstant: return((IEdmIntegerConstantExpression)expression); case EdmExpressionKind.StringConstant: return((IEdmStringConstantExpression)expression); case EdmExpressionKind.BinaryConstant: return((IEdmBinaryConstantExpression)expression); case EdmExpressionKind.BooleanConstant: return((IEdmBooleanConstantExpression)expression); case EdmExpressionKind.DateTimeOffsetConstant: return((IEdmDateTimeOffsetConstantExpression)expression); case EdmExpressionKind.DecimalConstant: return((IEdmDecimalConstantExpression)expression); case EdmExpressionKind.FloatingConstant: return((IEdmFloatingConstantExpression)expression); case EdmExpressionKind.GuidConstant: return((IEdmGuidConstantExpression)expression); case EdmExpressionKind.DurationConstant: return((IEdmDurationConstantExpression)expression); case EdmExpressionKind.DateConstant: return((IEdmDateConstantExpression)expression); case EdmExpressionKind.TimeOfDayConstant: return((IEdmTimeOfDayConstantExpression)expression); case EdmExpressionKind.Null: return((IEdmNullExpression)expression); case EdmExpressionKind.Path: { if (context == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_NoContextPath); } IEdmPathExpression pathExpression = (IEdmPathExpression)expression; IEdmValue result = context; #if NET35 // [EdmLib] Need to handle paths that bind to things other than properties. foreach (string hop in pathExpression.PathSegments) { result = FindProperty(hop, result); if (result == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop)); } } #else // Only Support Annotation in EntityType or ComplexType or Property or NavigationProperty. // Empty Path is not supported. foreach (string hop in pathExpression.PathSegments) { if (hop.Contains("@")) { var currentPathSegementInfos = hop.Split('@'); var propertyName = currentPathSegementInfos[0]; var termInfo = currentPathSegementInfos[1]; IEdmExpression termCastExpression = null; if (!Utils.StringIsNullOrWhitespace(termInfo)) { var termInfos = termInfo.Split('#'); if (termInfos.Length <= 2) { string termName = termInfos[0]; string qualifier = termInfos.Length == 2 ? termInfos[1] : null; if (Utils.StringIsNullOrWhitespace(propertyName) && this.getAnnotationExpressionForType != null) { termCastExpression = this.getAnnotationExpressionForType(this.edmModel, context.Type.Definition, termName, qualifier); } else if (!Utils.StringIsNullOrWhitespace(propertyName) && this.getAnnotationExpressionForProperty != null) { termCastExpression = this.getAnnotationExpressionForProperty(this.edmModel, context.Type.Definition, propertyName, termName, qualifier); } } } if (termCastExpression == null) { result = null; break; } result = this.Eval(termCastExpression, context); } else if (hop == "$count") { var edmCollectionValue = result as IEdmCollectionValue; if (edmCollectionValue != null) { result = new EdmIntegerConstant(edmCollectionValue.Elements.Count()); } else { result = null; break; } } else if (hop.Contains(".")) { if (this.edmModel == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_TypeCastNeedsEdmModel); } IEdmType typeSegmentClientType = this.resolveTypeFromName(hop, this.edmModel); if (typeSegmentClientType == null) { result = null; break; } IEdmTypeReference operandType = result.Type; EdmValueKind operandKind = result.ValueKind; if (operandKind == EdmValueKind.Collection) { List <IEdmDelayedValue> elementValues = new List <IEdmDelayedValue>(); var collection = result as IEdmCollectionValue; foreach (IEdmDelayedValue element in collection.Elements) { if (element.Value.Type.Definition.IsOrInheritsFrom(typeSegmentClientType)) { elementValues.Add(element); } } result = new EdmCollectionValue( new EdmCollectionTypeReference(new EdmCollectionType(typeSegmentClientType.GetTypeReference(false))), elementValues); } else if (operandKind != EdmValueKind.Structured || (operandKind == EdmValueKind.Structured && !operandType.Definition.IsOrInheritsFrom(typeSegmentClientType))) { result = null; break; } } else { result = FindProperty(hop, result); if (result == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop)); } } } #endif return(result); } case EdmExpressionKind.PropertyPath: case EdmExpressionKind.NavigationPropertyPath: { EdmUtil.CheckArgumentNull(context, "context"); IEdmPathExpression pathExpression = (IEdmPathExpression)expression; IEdmValue result = context; // [EdmLib] Need to handle paths that bind to things other than properties. foreach (string hop in pathExpression.PathSegments) { result = FindProperty(hop, result); if (result == null) { throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop)); } } return(result); } case EdmExpressionKind.FunctionApplication: { IEdmApplyExpression apply = (IEdmApplyExpression)expression; IEdmFunction target = apply.AppliedFunction; if (target != null) { IList <IEdmExpression> argumentExpressions = apply.Arguments.ToList(); IEdmValue[] arguments = new IEdmValue[argumentExpressions.Count()]; { int argumentIndex = 0; foreach (IEdmExpression argument in argumentExpressions) { arguments[argumentIndex++] = this.Eval(argument, context); } } //// Static validation will have checked that the number and types of arguments are correct, //// so those checks are not performed dynamically. Func <IEdmValue[], IEdmValue> operationEvaluator; if (this.builtInFunctions.TryGetValue(target, out operationEvaluator)) { return(operationEvaluator(arguments)); } if (this.lastChanceOperationApplier != null) { return(this.lastChanceOperationApplier(target.FullName(), arguments)); } } throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundFunction(target != null ? target.ToTraceString() : string.Empty)); } case EdmExpressionKind.If: { IEdmIfExpression ifExpression = (IEdmIfExpression)expression; if (((IEdmBooleanValue)this.Eval(ifExpression.TestExpression, context)).Value) { return(this.Eval(ifExpression.TrueExpression, context)); } return(this.Eval(ifExpression.FalseExpression, context)); } case EdmExpressionKind.IsType: { IEdmIsTypeExpression isType = (IEdmIsTypeExpression)expression; IEdmValue operand = this.Eval(isType.Operand, context); IEdmTypeReference targetType = isType.Type; return(new EdmBooleanConstant(MatchesType(targetType, operand))); } case EdmExpressionKind.Cast: { IEdmCastExpression castType = (IEdmCastExpression)expression; IEdmValue operand = this.Eval(castType.Operand, context); IEdmTypeReference targetType = castType.Type; return(Cast(targetType, operand)); } case EdmExpressionKind.Record: { IEdmRecordExpression record = (IEdmRecordExpression)expression; DelayedExpressionContext recordContext = new DelayedExpressionContext(this, context); List <IEdmPropertyValue> propertyValues = new List <IEdmPropertyValue>(); //// Static validation will have checked that the set of supplied properties are appropriate //// for the supplied type and have no duplicates, so those checks are not performed dynamically. foreach (IEdmPropertyConstructor propertyConstructor in record.Properties) { propertyValues.Add(new DelayedRecordProperty(recordContext, propertyConstructor)); } EdmStructuredValue result = new EdmStructuredValue(record.DeclaredType != null ? record.DeclaredType.AsStructured() : null, propertyValues); return(result); } case EdmExpressionKind.Collection: { IEdmCollectionExpression collection = (IEdmCollectionExpression)expression; DelayedExpressionContext collectionContext = new DelayedExpressionContext(this, context); List <IEdmDelayedValue> elementValues = new List <IEdmDelayedValue>(); //// Static validation will have checked that the result types of the element expressions are //// appropriate and so these checks are not performed dynamically. foreach (IEdmExpression element in collection.Elements) { elementValues.Add(this.MapLabeledExpressionToDelayedValue(element, collectionContext, context)); } EdmCollectionValue result = new EdmCollectionValue(collection.DeclaredType != null ? collection.DeclaredType.AsCollection() : null, elementValues); return(result); } case EdmExpressionKind.LabeledExpressionReference: { return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value); } case EdmExpressionKind.Labeled: return(this.MapLabeledExpressionToDelayedValue(expression, new DelayedExpressionContext(this, context), context).Value); case EdmExpressionKind.EnumMember: IEdmEnumMemberExpression enumMemberExpression = (IEdmEnumMemberExpression)expression; var enumMembers = enumMemberExpression.EnumMembers.ToList(); IEdmEnumType enumType = enumMembers.First().DeclaringType; IEdmEnumTypeReference enumTypeReference = new EdmEnumTypeReference(enumType, false); if (enumMembers.Count() == 1) { return(new EdmEnumValue(enumTypeReference, enumMemberExpression.EnumMembers.Single())); } else { if (!enumType.IsFlags || !EdmEnumValueParser.IsEnumIntegerType(enumType)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type {0} cannot be assigned with multi-values.", enumType.FullName())); } long result = 0; foreach (var enumMember in enumMembers) { long value = enumMember.Value.Value; result |= value; } return(new EdmEnumValue(enumTypeReference, new EdmEnumMemberValue(result))); } default: throw new InvalidOperationException(Strings.Edm_Evaluator_UnrecognizedExpressionKind(((int)expression.ExpressionKind).ToString(System.Globalization.CultureInfo.InvariantCulture))); } }
protected virtual void ProcessEnumMemberExpression(IEdmEnumMemberExpression expression) { this.ProcessExpression(expression); }
internal abstract void WriteEnumMemberExpressionElement(IEdmEnumMemberExpression expression);
/// <summary> /// Given a model element, see if it is marked as deprecated. /// </summary> /// <param name="model">The model containing the element</param> /// <param name="element">The IEdmElement to be validated to see if it's marked as deprecated.</param> /// <param name="message">The returned deprecation message if the element is deprecated.</param> /// <param name="version">The returned version if the element is deprecated, if specified.</param> /// <param name="date">The returned date if the element is deprecated, if specified.</param> /// <param name="removalDate">The returned removal date if the element is deprecated, if specified.</param> /// <returns>True if the element is marked as deprecated, otherwise false.</returns> private static bool IsDeprecated(IEdmModel model, IEdmElement element, out string message, out string version, out Date?date, out Date?removalDate) { if (!(element is IEdmPrimitiveType)) { IEdmVocabularyAnnotatable annotatedElement = element as IEdmVocabularyAnnotatable; if (annotatedElement != null) { foreach (IEdmVocabularyAnnotation annotation in GetRevisionAnnotations(model, annotatedElement)) { IEdmCollectionExpression collectionExpression = annotation.Value as IEdmCollectionExpression; if (collectionExpression != null) { foreach (IEdmExpression versionRecord in collectionExpression.Elements) { bool isDeprecated = false; message = string.Empty; version = string.Empty; date = null; removalDate = null; IEdmRecordExpression record = versionRecord as IEdmRecordExpression; if (record != null) { foreach (IEdmPropertyConstructor property in record.Properties) { switch (property.Name) { case RevisionKindProperty: IEdmEnumMemberExpression enumValue = property.Value as IEdmEnumMemberExpression; if (enumValue != null) { if (string.Equals(enumValue.EnumMembers.FirstOrDefault().Name, RevisionKindDeprecated, StringComparison.OrdinalIgnoreCase)) { isDeprecated = true; } else { continue; } } break; case RevisionVersionProperty: IEdmStringConstantExpression versionValue = property.Value as IEdmStringConstantExpression; if (versionValue != null) { version = versionValue.Value; } break; case RevisionDescriptionProperty: IEdmStringConstantExpression descriptionValue = property.Value as IEdmStringConstantExpression; if (descriptionValue != null) { message = descriptionValue.Value; } break; case RevisionDateProperty: IEdmDateConstantExpression dateValue = property.Value as IEdmDateConstantExpression; if (dateValue != null) { date = dateValue.Value; } break; case RevisionRemovalDateProperty: IEdmDateConstantExpression removalDateValue = property.Value as IEdmDateConstantExpression; if (removalDateValue != null) { removalDate = removalDateValue.Value; } break; default: break; } } } if (isDeprecated) { return(true); } } } } } } message = version = string.Empty; date = removalDate = null; return(false); }
private bool CheckForDeprecationOnType(OdcmObject odcmObject, IEdmVocabularyAnnotation revisionsAnnotation) { if (revisionsAnnotation != null) { IEdmCollectionExpression collectionExpression = revisionsAnnotation.Value as IEdmCollectionExpression; if (collectionExpression != null) { foreach (IEdmExpression versionRecord in collectionExpression.Elements) { bool isDeprecated = false; string message = string.Empty; string version = string.Empty; IEdmRecordExpression record = versionRecord as IEdmRecordExpression; if (record != null) { foreach (IEdmPropertyConstructor property in record.Properties) { switch (property.Name.ToLower()) { case "kind": IEdmEnumMemberExpression enumValue = property.Value as IEdmEnumMemberExpression; if (enumValue != null) { if (string.Equals(enumValue.EnumMembers.FirstOrDefault().Name, "deprecated", StringComparison.OrdinalIgnoreCase)) { isDeprecated = true; } else { continue; } } break; case "description": IEdmStringConstantExpression descriptionValue = property.Value as IEdmStringConstantExpression; if (descriptionValue != null) { message = descriptionValue.Value; } break; case "version": IEdmStringConstantExpression versionValue = property.Value as IEdmStringConstantExpression; if (versionValue != null) { version = versionValue.Value; } break; default: break; } } if (isDeprecated) { odcmObject.Deprecation = new OdcmDeprecation { Description = message, Version = version }; return(true); } } } } } return(false); }