/// <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);
        }
示例#2
0
        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;
                            }
                        }
                    }
                }
            }
        }
示例#4
0
        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);
        }
示例#5
0
 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)));
            }
        }
示例#8
0
 protected virtual void ProcessEnumMemberExpression(IEdmEnumMemberExpression expression)
 {
     this.ProcessExpression(expression);
 }
 internal abstract void WriteEnumMemberExpressionElement(IEdmEnumMemberExpression expression);
示例#10
0
        /// <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);
        }
示例#11
0
            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);
            }