Пример #1
0
        /// <summary>
        /// Creates a new ODataEntry from the specified entity set, instance, and type.
        /// </summary>
        /// <param name="entitySet">Entity set for the new entry.</param>
        /// <param name="value">Entity instance for the new entry.</param>
        /// <param name="entityType">Entity type for the new entry.</param>
        /// <returns>New ODataEntry with the specified entity set and type, property values from the specified instance.</returns>
        internal static ODataEntry CreateODataEntry(IEdmEntitySet entitySet, IEdmStructuredValue value, IEdmEntityType entityType)
        {
            var entry = new ODataEntry();
            entry.SetAnnotation(new ODataTypeAnnotation(entitySet, entityType));
            entry.Properties = value.PropertyValues.Select(p =>
            {
                object propertyValue;
                if (p.Value.ValueKind == EdmValueKind.Null)
                {
                    propertyValue = null;
                }
                else if (p.Value is IEdmPrimitiveValue)
                {
                    propertyValue = ((IEdmPrimitiveValue)p.Value).ToClrValue();
                }
                else
                {
                    Assert.Fail("Test only currently supports creating ODataEntry from IEdmPrimitiveValue instances.");
                    return null;
                }

                return new ODataProperty() { Name = p.Name, Value = propertyValue };
            });

            return entry;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ConventionalODataEntityMetadataBuilder"/> class.
        /// </summary>
        /// <param name="resolver">The URI resolver to use.</param>
        /// <param name="entitySetName">Name of the entity set the entity belongs to.</param>
        /// <param name="entityInstance">The entity instance to build metadata for.</param>
        /// <param name="conventions">The user-specified conventions to use.</param>
        internal ConventionalODataEntityMetadataBuilder(UriResolver resolver, string entitySetName, IEdmStructuredValue entityInstance, DataServiceUrlConventions conventions)
        {
            Util.CheckArgumentNullAndEmpty(entitySetName, "entitySetName");
            Util.CheckArgumentNull(entityInstance, "entityInstance");
            Util.CheckArgumentNull(conventions, "conventions");
            this.entitySetName = entitySetName;
            this.entityInstance = entityInstance;

            this.uriBuilder = new ConventionalODataUriBuilder(resolver, conventions);
            this.baseUri = resolver.BaseUriOrNull;
        }
        public void Init()
        {
            var entityContainer = new EdmEntityContainer("MyNamespace", "MyThing");

            var entityType = new EdmEntityType("MyNamespace", "EntityType");
            entityType.AddKeys(new EdmStructuralProperty(entityType, "Id", EdmCoreModel.Instance.GetInt32(false)));

            this.entitySet = this.entitySet = new EdmEntitySet(entityContainer, "EntitySet", entityType);
            this.structure = new EdmStructuredValueSimulator(entityType, new Dictionary<string, IEdmValue> { { "Id", EdmValueUtils.ConvertPrimitiveValue(1, null).Value } });

            this.metadataBuilder = new ConventionalODataEntityMetadataBuilder(new Uri("http://test/"), ((IEdmEntitySet)this.entitySet).Name, this.structure, DataServiceUrlConventions.Default);
        }
        /// <summary>
        /// Appends the key expression for the given entity to the given <see cref="StringBuilder"/>
        /// </summary>
        /// <param name="entity">The entity to build the key expression from.</param>
        /// <param name="builder">The builder to append onto.</param>
        internal void AppendKeyExpression(IEdmStructuredValue entity, StringBuilder builder)
        {
            Debug.Assert(entity != null, "entity != null");
            Debug.Assert(builder != null, "builder != null");

            IEdmEntityTypeReference edmEntityTypeReference = entity.Type as IEdmEntityTypeReference;

            if (edmEntityTypeReference == null || !edmEntityTypeReference.Key().Any())
            {
                throw Error.Argument(ErrorStrings.Content_EntityWithoutKey, "entity");
            }

            this.AppendKeyExpression(edmEntityTypeReference.Key().ToList(), p => p.Name, p => GetPropertyValue(entity.FindPropertyValue(p.Name), entity.Type), builder);
        }
Пример #5
0
        private IEdmValue FindProperty(string name, IEdmValue context)
        {
            IEdmValue           value = null;
            IEdmStructuredValue edmStructuredValue = context as IEdmStructuredValue;

            if (edmStructuredValue != null)
            {
                IEdmPropertyValue edmPropertyValue = edmStructuredValue.FindPropertyValue(name);
                if (edmPropertyValue != null)
                {
                    value = edmPropertyValue.Value;
                }
            }
            return(value);
        }
Пример #6
0
        public void Init()
        {
            var entityContainer = new EdmEntityContainer("MyNamespace", "MyThing");

            var entityType = new EdmEntityType("MyNamespace", "EntityType");

            entityType.AddKeys(new EdmStructuralProperty(entityType, "Id", EdmCoreModel.Instance.GetInt32(false)));

            this.entitySet = this.entitySet = new EdmEntitySet(entityContainer, "EntitySet", entityType);
            this.structure = new EdmStructuredValueSimulator(entityType, new Dictionary <string, IEdmValue> {
                { "Id", EdmValueUtils.ConvertPrimitiveValue(1, null).Value }
            });

            this.metadataBuilder = new ConventionalODataEntityMetadataBuilder(new Uri("http://test/"), ((IEdmEntitySet)this.entitySet).Name, this.structure, DataServiceUrlConventions.Default);
        }
Пример #7
0
        /// <summary>
        /// Tries to get a stream property of the specified name.
        /// </summary>
        /// <param name="entityInstance">The instance of the entity to get the stream property for.</param>
        /// <param name="streamPropertyName">The stream property name to find.</param>
        /// <param name="streamProperty">The stream property found.</param>
        /// <returns>true if the stream property was found or if the stream property name was null (default stream).
        /// false if the stream property doesn't exist.</returns>
        internal static bool TryGetStreamProperty(IEdmStructuredValue entityInstance, string streamPropertyName, out IEdmProperty streamProperty)
        {
            Debug.Assert(entityInstance != null, "entityInstance != null");

            streamProperty = null;
            if (streamPropertyName != null)
            {
                streamProperty = entityInstance.Type.AsEntity().FindProperty(streamPropertyName);
                if (streamProperty == null)
                {
                    return(false);
                }
            }

            return(true);
        }
        public void Init()
        {
            this.defaultBaseUri = new Uri("http://odata.org/base/");
            this.builder = new ODataConventionalUriBuilder(this.defaultBaseUri, UrlConvention.CreateWithExplicitValue(false));

            this.model = TestModel.BuildDefaultTestModel();
            this.defaultProductInstance = TestModel.BuildDefaultProductValue(TestModel.GetEntityType(this.model, "TestModel.Product"));
            this.defaultMultipleKeyInstance = TestModel.BuildDefaultMultipleKeyValue(this.model);

            this.idPropertyList = new Dictionary<string, IEdmValue>()
                {
                    { "Id", new EdmIntegerConstant(EdmCoreModel.Instance.GetInt32(false), 42) }
                };

            this.typeWithStringKey = new EdmEntityType("Test.Model", "StringKey");
            this.typeWithStringKey.AddKeys(this.typeWithStringKey.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String));
        }
        public ODataConventionalUriBuilderTests()
        {
            this.defaultBaseUri = new Uri("http://odata.org/base/");
            this.builder        = new ODataConventionalUriBuilder(this.defaultBaseUri, ODataUrlKeyDelimiter.Parentheses);

            this.model = TestModel.BuildDefaultTestModel();
            this.defaultProductInstance     = TestModel.BuildDefaultProductValue(TestModel.GetEntityType(this.model, "TestModel.Product"));
            this.defaultMultipleKeyInstance = TestModel.BuildDefaultMultipleKeyValue(this.model);

            this.idPropertyList = new Dictionary <string, IEdmValue>()
            {
                { "Id", new EdmIntegerConstant(EdmCoreModel.Instance.GetInt32(false), 42) }
            };

            this.typeWithStringKey = new EdmEntityType("Test.Model", "StringKey");
            this.typeWithStringKey.AddKeys(this.typeWithStringKey.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String));
        }
Пример #10
0
        private static IEdmValue FindProperty(string name, IEdmValue context)
        {
            IEdmValue result = null;

            IEdmStructuredValue structuredContext = context as IEdmStructuredValue;

            if (structuredContext != null)
            {
                IEdmPropertyValue propertyValue = structuredContext.FindPropertyValue(name);
                if (propertyValue != null)
                {
                    result = propertyValue.Value;
                }
            }

            return(result);
        }
Пример #11
0
        private static T GetPropertyValue <T>(this IEdmModel model, IEdmStructuredValue context, IEdmEntityType contextType, IEdmValueTerm term, IEdmProperty property, string qualifier, Func <IEdmExpression, IEdmStructuredValue, T> evaluator)
        {
            IEnumerable <IEdmValueAnnotation> annotations = model.FindVocabularyAnnotations <IEdmValueAnnotation>(contextType, term, qualifier);

            if (annotations.Count() != 1)
            {
                throw new InvalidOperationException("Type " + contextType.ToTraceString() + " must have a single annotation with term " + term.ToTraceString());
            }

            var annotationValue = annotations.Single().Value as IEdmRecordExpression;

            if (annotationValue == null)
            {
                throw new InvalidOperationException("Type " + contextType.ToTraceString() + " must have a single annotation containing a record expression with term " + term.ToTraceString());
            }

            var propertyConstructor = annotationValue.FindProperty(property.Name);

            return(propertyConstructor != null?evaluator(propertyConstructor.Value, context) : default(T));
        }
Пример #12
0
        private static void CompareStructuralValue(IEdmValue edmValue, IEnumerable <ODataProperty> properties, AssertionHandler assert)
        {
            IEdmStructuredValue structuredEdmValue = (IEdmStructuredValue)edmValue;

            if (properties != null)
            {
                // Use FindPropertyValue
                foreach (ODataProperty property in properties)
                {
                    IEdmPropertyValue edmPropertyValue = structuredEdmValue.FindPropertyValue(property.Name);
                    CompareProperty(edmPropertyValue, property, assert);
                }

                // Enumerate the properties
                CompareProperties(structuredEdmValue.PropertyValues, properties, assert);
            }
            else
            {
                assert.IsTrue(
                    structuredEdmValue.PropertyValues == null || structuredEdmValue.PropertyValues.Count() == 0,
                    "Expected empty structured value.");
            }
        }
Пример #13
0
 public IEdmValue Evaluate(IEdmExpression expression, IEdmStructuredValue context, IEdmTypeReference targetType)
 {
     EdmUtil.CheckArgumentNull <IEdmExpression>(expression, "expression");
     EdmUtil.CheckArgumentNull <IEdmTypeReference>(targetType, "targetType");
     return(EdmExpressionEvaluator.AssertType(targetType, this.Eval(expression, context)));
 }
Пример #14
0
 internal ConventionalODataEntityMetadataBuilder(Uri baseUri, string entitySetName, IEdmStructuredValue entityInstance, DataServiceUrlConventions conventions)
     : this(UriResolver.CreateFromBaseUri(baseUri, "baseUri"), entitySetName, entityInstance, conventions)
 {
 }
Пример #15
0
        /// <summary>
        /// Evaluates an expression in the context of a value.
        /// </summary>
        /// <param name="expression">Expression to evaluate.</param>
        /// <param name="context">Value to use as context in evaluating the expression. Cannot be null if the expression contains paths.</param>
        /// <returns>The value that results from evaluating the expression in the context of the supplied value.</returns>
        public IEdmValue Evaluate(IEdmExpression expression, IEdmStructuredValue context)
        {
            EdmUtil.CheckArgumentNull(expression, "expression");

            return(this.Eval(expression, context));
        }
Пример #16
0
        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)));
            }
        }
            internal override Microsoft.OData.Client.ODataResourceMetadataBuilder GetEntityMetadataBuilder(string entitySetName, IEdmStructuredValue entityInstance)
            {
                if (this.GetMetadataBuilderFunc == null)
                {
                    return(base.GetEntityMetadataBuilder(entitySetName, entityInstance));
                }

                return(this.GetMetadataBuilderFunc(entitySetName, entityInstance));
            }
Пример #18
0
        private object AsClrObject(IEdmValue edmValue, Type clrObjectType)
        {
            EdmUtil.CheckArgumentNull(edmValue, "edmValue");
            EdmUtil.CheckArgumentNull(clrObjectType, "clrObjectType");

            if (edmValue is IEdmNullValue)
            {
                return(null);
            }

            IEdmStructuredValue edmStructuredValue = edmValue as IEdmStructuredValue;

            if (edmStructuredValue == null)
            {
                if (edmValue is IEdmCollectionValue)
                {
                    throw new InvalidCastException(Strings.EdmToClr_CannotConvertEdmCollectionValueToClrType(clrObjectType.FullName));
                }
                else
                {
                    throw new InvalidCastException(Strings.EdmToClr_CannotConvertEdmValueToClrType(GetEdmValueInterfaceName(edmValue), clrObjectType.FullName));
                }
            }

            object clrObject;

            if (this.convertedObjects.TryGetValue(edmStructuredValue, out clrObject))
            {
                return(clrObject);
            }

            // By convention we only support mapping structured values to a CLR class.
            if (!clrObjectType.IsClass())
            {
                throw new InvalidCastException(Strings.EdmToClr_StructuredValueMappedToNonClass);
            }

            // Try user-defined logic before the default logic.
            bool clrObjectInitialized;

            if (this.tryCreateObjectInstanceDelegate != null && this.tryCreateObjectInstanceDelegate(edmStructuredValue, clrObjectType, this, out clrObject, out clrObjectInitialized))
            {
                // The user-defined logic might have produced null, which is Ok, but we need to null the type in to keep them in sync.
                if (clrObject != null)
                {
                    Type newClrObjectType = clrObject.GetType();
                    if (!clrObjectType.IsAssignableFrom(newClrObjectType))
                    {
                        throw new InvalidCastException(Strings.EdmToClr_TryCreateObjectInstanceReturnedWrongObject(newClrObjectType.FullName, clrObjectType.FullName));
                    }

                    clrObjectType = newClrObjectType;
                }
            }
            else
            {
                // Default instance creation logic: use Activator to create the new CLR object from the type.
                clrObject            = Activator.CreateInstance(clrObjectType);
                clrObjectInitialized = false;
            }

            // Cache the object before populating its properties as their values might refer to the object.
            this.convertedObjects[edmStructuredValue] = clrObject;

            if (!clrObjectInitialized && clrObject != null)
            {
                this.PopulateObjectProperties(edmStructuredValue, clrObject, clrObjectType);
            }

            return(clrObject);
        }
Пример #19
0
            /// <summary>
            /// Create an instance of a CLR type based on <see cref="IEdmValue"/> and <see cref="Type"/>.
            /// </summary>
            /// <param name="context">The data service context.</param>
            /// /// <param name="edmValue">The <see cref="IEdmStructuredValue"/> for which the <paramref name="objectInstance"/> needs to be created.</param>
            /// <param name="clrType">The CLR type of the object instance.</param>
            /// <param name="objectInstance">A CLR object instance created for the <paramref name="edmValue"/></param>
            /// <param name="objectInstanceInitialized">True if all properties of the created <paramref name="objectInstance"/> are initialized.
            /// False if properties of the created instance should be initialized using the default <see cref="EdmToClrConverter"/> logic.</param>
            /// <returns>True if the <paramref name="objectInstance"/> is created, else false.</returns>
            private static bool TryCreateClientObjectInstance(DataServiceContext context, IEdmStructuredValue edmValue, Type clrType, out object objectInstance, out bool objectInstanceInitialized)
            {
                var  clientStructuredValue = edmValue as ClientEdmStructuredValue;
                Type realClientType        = clrType;

                if (clientStructuredValue != null)
                {
                    var clientTypeAnnotation = context.Model.GetClientTypeAnnotation(edmValue.Type.Definition.FullName());
                    realClientType = clientTypeAnnotation.ElementType;
                }

                if (realClientType.IsSubclassOf(clrType))
                {
                    objectInstance = Activator.CreateInstance(realClientType);
                }
                else
                {
                    objectInstance = Activator.CreateInstance(clrType);
                }

                objectInstanceInitialized = false;
                return(true);
            }
Пример #20
0
 /// <summary>
 /// Appends to create the entity instance URI for the specified <paramref name="entityInstance"/>.
 /// </summary>
 /// <param name="baseUri">The URI to append to</param>
 /// <param name="entityInstance">The entity instance to use.</param>
 /// <returns>
 /// The entity instance URI.
 /// </returns>
 internal virtual Uri BuildEntityInstanceUri(Uri baseUri, IEdmStructuredValue entityInstance)
            internal override Microsoft.OData.Client.ODataEntityMetadataBuilder GetEntityMetadataBuilder(string entitySetName, IEdmStructuredValue entityInstance)
            {
                if (this.GetMetadataBuilderFunc == null)
                {
                    return base.GetEntityMetadataBuilder(entitySetName, entityInstance);
                }

                return this.GetMetadataBuilderFunc(entitySetName, entityInstance);
            }
Пример #22
0
 /// <summary>
 /// Create an instance of a CLR type based on <see cref="IEdmValue"/> and <see cref="Type"/>.
 /// </summary>
 /// <param name="edmValue">The <see cref="IEdmStructuredValue"/> for which the <paramref name="objectInstance"/> needs to be created.</param>
 /// <param name="clrType">The CLR type of the object instance.</param>
 /// <param name="converter">The converter instance calling this method.</param>
 /// <param name="objectInstance">A CLR object instance created for the <paramref name="edmValue"/></param>
 /// <param name="objectInstanceInitialized">True if all properties of the created <paramref name="objectInstance"/> are initialized.
 /// False if properties of the created instance should be initialized using the default <see cref="EdmToClrConverter"/> logic.</param>
 /// <returns>True if the <paramref name="objectInstance"/> is created, else false.</returns>
 internal bool TryCreateObjectInstance(IEdmStructuredValue edmValue, Type clrType, EdmToClrConverter converter, out object objectInstance, out bool objectInstanceInitialized)
 {
     return(TryCreateClientObjectInstance(this.dataServiceContext, edmValue, clrType, out objectInstance, out objectInstanceInitialized));
 }
 public Microsoft.OData.Client.ODataEntityMetadataBuilder GetMetadataBuilder(string entitySetName, IEdmStructuredValue entityInstance)
 {
     return base.GetEntityMetadataBuilder(entitySetName, entityInstance);
 }
Пример #24
0
        private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context)
        {
            Func <IEdmValue[], IEdmValue> func = null;
            IEdmStructuredTypeReference   edmStructuredTypeReference;
            IEdmCollectionTypeReference   edmCollectionTypeReference;
            object            traceString;
            EdmExpressionKind expressionKind = expression.ExpressionKind;

            switch (expressionKind)
            {
            case EdmExpressionKind.BinaryConstant:
            {
                return((IEdmBinaryConstantExpression)expression);
            }

            case EdmExpressionKind.BooleanConstant:
            {
                return((IEdmBooleanConstantExpression)expression);
            }

            case EdmExpressionKind.DateTimeConstant:
            {
                return((IEdmDateTimeConstantExpression)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.IntegerConstant:
            {
                return((IEdmIntegerConstantExpression)expression);
            }

            case EdmExpressionKind.StringConstant:
            {
                return((IEdmStringConstantExpression)expression);
            }

            case EdmExpressionKind.TimeConstant:
            {
                return((IEdmTimeConstantExpression)expression);
            }

            case EdmExpressionKind.Null:
            {
                return((IEdmNullExpression)expression);
            }

            case EdmExpressionKind.Record:
            {
                IEdmRecordExpression edmRecordExpression = (IEdmRecordExpression)expression;
                EdmExpressionEvaluator.DelayedExpressionContext delayedExpressionContext = new EdmExpressionEvaluator.DelayedExpressionContext(this, context);
                List <IEdmPropertyValue> edmPropertyValues = new List <IEdmPropertyValue>();
                foreach (IEdmPropertyConstructor property in edmRecordExpression.Properties)
                {
                    edmPropertyValues.Add(new EdmExpressionEvaluator.DelayedRecordProperty(delayedExpressionContext, property));
                }
                if (edmRecordExpression.DeclaredType != null)
                {
                    edmStructuredTypeReference = edmRecordExpression.DeclaredType.AsStructured();
                }
                else
                {
                    edmStructuredTypeReference = null;
                }
                EdmStructuredValue edmStructuredValue = new EdmStructuredValue(edmStructuredTypeReference, edmPropertyValues);
                return(edmStructuredValue);
            }

            case EdmExpressionKind.Collection:
            {
                IEdmCollectionExpression edmCollectionExpression = (IEdmCollectionExpression)expression;
                EdmExpressionEvaluator.DelayedExpressionContext delayedExpressionContext1 = new EdmExpressionEvaluator.DelayedExpressionContext(this, context);
                List <IEdmDelayedValue> edmDelayedValues = new List <IEdmDelayedValue>();
                foreach (IEdmExpression element in edmCollectionExpression.Elements)
                {
                    edmDelayedValues.Add(this.MapLabeledExpressionToDelayedValue(element, delayedExpressionContext1, context));
                }
                if (edmCollectionExpression.DeclaredType != null)
                {
                    edmCollectionTypeReference = edmCollectionExpression.DeclaredType.AsCollection();
                }
                else
                {
                    edmCollectionTypeReference = null;
                }
                EdmCollectionValue edmCollectionValue = new EdmCollectionValue(edmCollectionTypeReference, edmDelayedValues);
                return(edmCollectionValue);
            }

            case EdmExpressionKind.Path:
            {
                EdmUtil.CheckArgumentNull <IEdmStructuredValue>(context, "context");
                IEdmPathExpression edmPathExpression = (IEdmPathExpression)expression;
                IEdmValue          edmValue          = context;
                foreach (string path in edmPathExpression.Path)
                {
                    edmValue = this.FindProperty(path, edmValue);
                    if (edmValue != null)
                    {
                        continue;
                    }
                    throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(path));
                }
                return(edmValue);
            }

            case EdmExpressionKind.ParameterReference:
            case EdmExpressionKind.FunctionReference:
            case EdmExpressionKind.PropertyReference:
            case EdmExpressionKind.ValueTermReference:
            case EdmExpressionKind.EntitySetReference:
            case EdmExpressionKind.EnumMemberReference:
            {
                throw new InvalidOperationException(string.Concat("Not yet implemented: evaluation of ", expression.ExpressionKind.ToString(), " expressions."));
            }

            case EdmExpressionKind.If:
            {
                IEdmIfExpression edmIfExpression = (IEdmIfExpression)expression;
                if (!((IEdmBooleanValue)this.Eval(edmIfExpression.TestExpression, context)).Value)
                {
                    return(this.Eval(edmIfExpression.FalseExpression, context));
                }
                else
                {
                    return(this.Eval(edmIfExpression.TrueExpression, context));
                }
            }

            case EdmExpressionKind.AssertType:
            {
                IEdmAssertTypeExpression edmAssertTypeExpression = (IEdmAssertTypeExpression)expression;
                IEdmValue         edmValue1 = this.Eval(edmAssertTypeExpression.Operand, context);
                IEdmTypeReference type      = edmAssertTypeExpression.Type;
                return(EdmExpressionEvaluator.AssertType(type, edmValue1));
            }

            case EdmExpressionKind.IsType:
            {
                IEdmIsTypeExpression edmIsTypeExpression = (IEdmIsTypeExpression)expression;
                IEdmValue            edmValue2           = this.Eval(edmIsTypeExpression.Operand, context);
                IEdmTypeReference    edmTypeReference    = edmIsTypeExpression.Type;
                return(new EdmBooleanConstant(EdmExpressionEvaluator.MatchesType(edmTypeReference, edmValue2)));
            }

            case EdmExpressionKind.FunctionApplication:
            {
                IEdmApplyExpression             edmApplyExpression             = (IEdmApplyExpression)expression;
                IEdmExpression                  appliedFunction                = edmApplyExpression.AppliedFunction;
                IEdmFunctionReferenceExpression edmFunctionReferenceExpression = appliedFunction as IEdmFunctionReferenceExpression;
                if (edmFunctionReferenceExpression != null)
                {
                    IList <IEdmExpression> list          = edmApplyExpression.Arguments.ToList <IEdmExpression>();
                    IEdmValue[]            edmValueArray = new IEdmValue[list.Count <IEdmExpression>()];
                    int num = 0;
                    foreach (IEdmExpression edmExpression in list)
                    {
                        int num1 = num;
                        num = num1 + 1;
                        edmValueArray[num1] = this.Eval(edmExpression, context);
                    }
                    IEdmFunction referencedFunction = edmFunctionReferenceExpression.ReferencedFunction;
                    if (referencedFunction.IsBad() || !this.builtInFunctions.TryGetValue(referencedFunction, out func))
                    {
                        if (this.lastChanceFunctionApplier != null)
                        {
                            return(this.lastChanceFunctionApplier(referencedFunction.FullName(), edmValueArray));
                        }
                    }
                    else
                    {
                        return(func(edmValueArray));
                    }
                }
                if (edmFunctionReferenceExpression != null)
                {
                    traceString = edmFunctionReferenceExpression.ReferencedFunction.ToTraceString();
                }
                else
                {
                    traceString = string.Empty;
                }
                throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundFunction(traceString));
            }

            case EdmExpressionKind.LabeledExpressionReference:
            {
                return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value);
            }

            case EdmExpressionKind.Labeled:
            {
                return(this.MapLabeledExpressionToDelayedValue(expression, new EdmExpressionEvaluator.DelayedExpressionContext(this, context), context).Value);
            }
            }
            int expressionKind1 = (int)expression.ExpressionKind;

            throw new InvalidOperationException(Strings.Edm_Evaluator_UnrecognizedExpressionKind(expressionKind1.ToString(CultureInfo.InvariantCulture)));
        }
Пример #25
0
        private static bool AssertOrMatchStructuredType(IEdmStructuredTypeReference structuredTargetType, IEdmStructuredValue structuredValue, bool testPropertyTypes, List <IEdmPropertyValue> newProperties)
        {
            bool flag;
            IEdmTypeReference type = structuredValue.Type;

            if (type == null || type.TypeKind() == EdmTypeKind.Row || structuredTargetType.StructuredDefinition().InheritsFrom(type.AsStructured().StructuredDefinition()))
            {
                HashSetInternal <IEdmPropertyValue>  edmPropertyValues = new HashSetInternal <IEdmPropertyValue>();
                IEnumerator <IEdmStructuralProperty> enumerator        = structuredTargetType.StructuralProperties().GetEnumerator();
                using (enumerator)
                {
                    while (enumerator.MoveNext())
                    {
                        IEdmProperty      current          = enumerator.Current;
                        IEdmPropertyValue edmPropertyValue = structuredValue.FindPropertyValue(current.Name);
                        if (edmPropertyValue != null)
                        {
                            edmPropertyValues.Add(edmPropertyValue);
                            if (!testPropertyTypes)
                            {
                                continue;
                            }
                            if (newProperties == null)
                            {
                                if (EdmExpressionEvaluator.MatchesType(current.Type, edmPropertyValue.Value))
                                {
                                    continue;
                                }
                                flag = false;
                                return(flag);
                            }
                            else
                            {
                                newProperties.Add(new EdmPropertyValue(edmPropertyValue.Name, EdmExpressionEvaluator.AssertType(current.Type, edmPropertyValue.Value)));
                            }
                        }
                        else
                        {
                            flag = false;
                            return(flag);
                        }
                    }
                    if (structuredTargetType.IsEntity())
                    {
                        IEnumerator <IEdmNavigationProperty> enumerator1 = structuredTargetType.AsEntity().NavigationProperties().GetEnumerator();
                        using (enumerator1)
                        {
                            while (enumerator1.MoveNext())
                            {
                                IEdmNavigationProperty edmNavigationProperty = enumerator1.Current;
                                IEdmPropertyValue      edmPropertyValue1     = structuredValue.FindPropertyValue(edmNavigationProperty.Name);
                                if (edmPropertyValue1 != null)
                                {
                                    if (!testPropertyTypes || EdmExpressionEvaluator.MatchesType(edmNavigationProperty.Type, edmPropertyValue1.Value, false))
                                    {
                                        edmPropertyValues.Add(edmPropertyValue1);
                                        if (newProperties == null)
                                        {
                                            continue;
                                        }
                                        newProperties.Add(edmPropertyValue1);
                                    }
                                    else
                                    {
                                        flag = false;
                                        return(flag);
                                    }
                                }
                                else
                                {
                                    flag = false;
                                    return(flag);
                                }
                            }
                        }
                    }
                    if (newProperties != null)
                    {
                        IEnumerator <IEdmPropertyValue> enumerator2 = structuredValue.PropertyValues.GetEnumerator();
                        using (enumerator2)
                        {
                            while (enumerator2.MoveNext())
                            {
                                IEdmPropertyValue current1 = enumerator2.Current;
                                if (edmPropertyValues.Contains(current1))
                                {
                                    continue;
                                }
                                newProperties.Add(current1);
                            }
                        }
                    }
                    return(true);
                }
                return(flag);
            }
            else
            {
                return(false);
            }
        }
            /// <summary>
            /// Appends to create the entity instance URI for the specified <paramref name="entityInstance"/>.
            /// </summary>
            /// <param name="baseUri">The URI to append to</param>
            /// <param name="entityInstance">The entity instance to use.</param>
            /// <returns>
            /// The entity instance URI.
            /// </returns>
            internal override Uri BuildEntityInstanceUri(Uri baseUri, IEdmStructuredValue entityInstance)
            {
                var builder = new StringBuilder();
                if (baseUri != null)
                {
                    builder.Append(UriUtil.UriToString(baseUri));
                }

                this.conventions.AppendKeyExpression(entityInstance, builder);
                return UriUtil.CreateUri(builder.ToString(), UriKind.RelativeOrAbsolute);
            }
Пример #27
0
 /// <summary>
 /// Appends to create the entity instance URI for the specified <paramref name="entityInstance"/>.
 /// </summary>
 /// <param name="baseUri">The URI to append to</param>
 /// <param name="entityInstance">The entity instance to use.</param>
 /// <returns>
 /// The entity instance URI.
 /// </returns>
 internal virtual Uri BuildEntityInstanceUri(Uri baseUri, IEdmStructuredValue entityInstance)
 public Microsoft.OData.Client.ODataResourceMetadataBuilder GetMetadataBuilder(string entitySetName, IEdmStructuredValue entityInstance)
 {
     return(base.GetEntityMetadataBuilder(entitySetName, entityInstance));
 }
Пример #29
0
        /// <summary>
        /// Tries to get a stream property of the specified name.
        /// </summary>
        /// <param name="entityInstance">The instance of the entity to get the stream property for.</param>
        /// <param name="streamPropertyName">The stream property name to find.</param>
        /// <param name="streamProperty">The stream property found.</param>
        /// <returns>true if the stream property was found or if the stream property name was null (default stream).
        /// false if the stream property doesn't exist.</returns>
        internal static bool TryGetStreamProperty(IEdmStructuredValue entityInstance, string streamPropertyName, out IEdmProperty streamProperty)
        {
            Debug.Assert(entityInstance != null, "entityInstance != null");

            streamProperty = null;
            if (streamPropertyName != null)
            {
                streamProperty = entityInstance.Type.AsEntity().FindProperty(streamPropertyName);
                if (streamProperty == null)
                {
                    return false;
                }
            }

            return true;
        }
Пример #30
0
 /// <summary>
 /// Registers the <paramref name="clrObject"/> corresponding to the <paramref name="edmValue"/>.
 /// All subsequent conversions from this <paramref name="edmValue"/> performed by this instance of <see cref="EdmToClrConverter"/> will return the specified
 /// <paramref name="clrObject"/>. Registration is required to support graph consistency and loops during conversion process.
 /// This method should be called inside the <see cref="TryCreateObjectInstance"/> delegate if the delegate is calling back into <see cref="EdmToClrConverter"/>
 /// in order to populate properties of the <paramref name="clrObject"/>.
 /// </summary>
 /// <param name="edmValue">The EDM value.</param>
 /// <param name="clrObject">The CLR object.</param>
 public void RegisterConvertedObject(IEdmStructuredValue edmValue, object clrObject)
 {
     this.convertedObjects.Add(edmValue, clrObject);
 }
        private void SetupValues()
        {
            IEdmEntityType person = (IEdmEntityType)this.baseModel.FindType("foo.Person");
            IEdmEntityType professional = (IEdmEntityType)this.baseModel.FindType("foo.Professional");
            IEdmEntityType address = (IEdmEntityType)this.baseModel.FindType("foo.Address");

            // ?? no EdmComplexValue
            var zipMain = new EdmPropertyValue("Main", new EdmStringConstant("98052"));
            var zipExtension = new EdmPropertyValue("Extension", new EdmStringConstant("0000"));
            var zipValue = new EdmPropertyValue("Zip", new EdmStructuredValue(null, new EdmPropertyValue[] { zipMain, zipExtension }));

            EdmPropertyValue address1Number = new EdmPropertyValue("Number", new EdmIntegerConstant(null, 1));
            EdmPropertyValue address1Street = new EdmPropertyValue("Street", new EdmStringConstant(null, "Joey Ramone Place"));
            EdmPropertyValue address1City = new EdmPropertyValue("City", new EdmStringConstant(null, "New York"));
            EdmPropertyValue address1State = new EdmPropertyValue("State", new EdmStringConstant(null, "New York"));
            EdmPropertyValue[] address1Properties = new EdmPropertyValue[] { address1Number, address1Street, address1City, address1State, zipValue };
            EdmStructuredValue address1Value = new EdmStructuredValue(new EdmEntityTypeReference(address, true), address1Properties);

            var phoneLocal = new EdmPropertyValue("Local", new EdmIntegerConstant(9991234));
            var phoneValue = new EdmPropertyValue("WorkPhone", new EdmStructuredValue(null, new EdmPropertyValue[] { phoneLocal }));
            var contactInfoValue = new EdmPropertyValue("ContactInfo", new EdmStructuredValue(null, new EdmPropertyValue[] { phoneValue }));

            EdmPropertyValue person1Name = new EdmPropertyValue("Name", new EdmStringConstant(null, "Joey Ramone"));
            EdmPropertyValue person1Birthday = new EdmPropertyValue("Birthday", new EdmDateTimeOffsetConstant(null, new DateTimeOffset(1951, 5, 19, 0, 0, 0, TimeSpan.Zero)));
            EdmPropertyValue person1CoolnessIndex = new EdmPropertyValue("CoolnessIndex", new EdmIntegerConstant(null, Int32.MaxValue));
            EdmPropertyValue person1Living = new EdmPropertyValue("Living", new EdmBooleanConstant(false));
            EdmPropertyValue person1Famous = new EdmPropertyValue("Famous", new EdmBooleanConstant(null, true));
            EdmPropertyValue person1Address = new EdmPropertyValue("Address", address1Value);

            EdmPropertyValue[] person1Properties = new EdmPropertyValue[] { person1Name, person1Birthday, person1CoolnessIndex, person1Living, person1Famous, person1Address, contactInfoValue };
            this.personValue = new EdmStructuredValue(new EdmEntityTypeReference(person, false), person1Properties);

            this.professionalValue = new EdmStructuredValue(new EdmEntityTypeReference(professional, false), person1Properties);
        }
        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.DateTimeConstant:
                return((IEdmDateTimeConstantExpression)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.TimeConstant:
                return((IEdmTimeConstantExpression)expression);

            case EdmExpressionKind.Null:
                return((IEdmNullExpression)expression);

            case EdmExpressionKind.Path:
            {
                EdmUtil.CheckArgumentNull(context, "context");

                IEdmPathExpression pathExpression = (IEdmPathExpression)expression;
                IEdmValue          result         = context;

                foreach (string hop in pathExpression.Path)
                {
                    result = this.FindProperty(hop, result);

                    if (result == null)
                    {
                        throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundPath(hop));
                    }
                }

                return(result);
            }

            case EdmExpressionKind.FunctionApplication:
            {
                IEdmApplyExpression             apply                   = (IEdmApplyExpression)expression;
                IEdmExpression                  targetReference         = apply.AppliedFunction;
                IEdmFunctionReferenceExpression targetFunctionReference = targetReference as IEdmFunctionReferenceExpression;
                if (targetFunctionReference != 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);
                        }
                    }

                    IEdmFunction target = targetFunctionReference.ReferencedFunction;
                    if (!target.IsBad())
                    {
                        //// Static validation will have checked that the number and types of arguments are correct,
                        //// so those checks are not performed dynamically.

                        Func <IEdmValue[], IEdmValue> functionEvaluator;
                        if (this.builtInFunctions.TryGetValue(target, out functionEvaluator))
                        {
                            return(functionEvaluator(arguments));
                        }
                    }

                    if (this.lastChanceFunctionApplier != null)
                    {
                        return(this.lastChanceFunctionApplier(target.FullName(), arguments));
                    }
                }

                throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundFunction(targetFunctionReference != null ? targetFunctionReference.ReferencedFunction.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.AssertType:
            {
                IEdmAssertTypeExpression assertType = (IEdmAssertTypeExpression)expression;

                IEdmValue         operand    = this.Eval(assertType.Operand, context);
                IEdmTypeReference targetType = assertType.Type;

                return(AssertType(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.ParameterReference:
            case EdmExpressionKind.FunctionReference:
            case EdmExpressionKind.PropertyReference:
            case EdmExpressionKind.ValueTermReference:
            case EdmExpressionKind.EntitySetReference:
            case EdmExpressionKind.EnumMemberReference:
                throw new InvalidOperationException("Not yet implemented: evaluation of " + expression.ExpressionKind.ToString() + " expressions.");

            default:
                throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnrecognizedExpressionKind(((int)expression.ExpressionKind).ToString(System.Globalization.CultureInfo.InvariantCulture)));
            }
        }
 protected ODataUriBuilderBaseTests()
 {
     this.defaultBaseUri = new Uri("http://odata.org/base/");
     this.model = TestModel.BuildDefaultTestModel();
     this.defaultProductInstance = TestModel.BuildDefaultProductValue(TestModel.GetEntityType(this.model, "TestModel.Product"));
 }
Пример #34
0
        private static bool AssertOrMatchStructuredType(IEdmStructuredTypeReference structuredTargetType, IEdmStructuredValue structuredValue, bool testPropertyTypes, List <IEdmPropertyValue> newProperties)
        {
            // If the value has a nominal type, the target type must be derived from the nominal type for a type match to be possible.
            IEdmTypeReference operandType = structuredValue.Type;

            if (operandType != null && !structuredTargetType.StructuredDefinition().InheritsFrom(operandType.AsStructured().StructuredDefinition()))
            {
                return(false);
            }

            HashSetInternal <IEdmPropertyValue> visitedProperties = new HashSetInternal <IEdmPropertyValue>();

            foreach (IEdmProperty property in structuredTargetType.StructuralProperties())
            {
                IEdmPropertyValue propertyValue = structuredValue.FindPropertyValue(property.Name);
                if (propertyValue == null)
                {
                    return(false);
                }

                visitedProperties.Add(propertyValue);
                if (testPropertyTypes)
                {
                    if (newProperties != null)
                    {
                        newProperties.Add(new EdmPropertyValue(propertyValue.Name, Cast(property.Type, propertyValue.Value)));
                    }
                    else if (!MatchesType(property.Type, propertyValue.Value))
                    {
                        return(false);
                    }
                }
            }

            if (structuredTargetType.IsEntity())
            {
                foreach (IEdmNavigationProperty property in structuredTargetType.AsEntity().NavigationProperties())
                {
                    IEdmPropertyValue propertyValue = structuredValue.FindPropertyValue(property.Name);
                    if (propertyValue == null)
                    {
                        return(false);
                    }

                    // Make a superficial test of the navigation property value--check that it has a valid set of properties,
                    // but don't test their types.
                    if (testPropertyTypes && !MatchesType(property.Type, propertyValue.Value, false))
                    {
                        return(false);
                    }

                    visitedProperties.Add(propertyValue);
                    if (newProperties != null)
                    {
                        newProperties.Add(propertyValue);
                    }
                }
            }

            //// Allow property values not mentioned in the target type, whether or not the target type is open.

            if (newProperties != null)
            {
                foreach (IEdmPropertyValue propertyValue in structuredValue.PropertyValues)
                {
                    if (!visitedProperties.Contains(propertyValue))
                    {
                        newProperties.Add(propertyValue);
                    }
                }
            }

            return(true);
        }
Пример #35
0
        /// <summary>
        /// Evaluates an expression in the context of a value and a target type.
        /// </summary>
        /// <typeparam name="T">The CLR type of the value to be returned.</typeparam>
        /// <param name="expression">Expression to evaluate.</param>
        /// <param name="context">Value to use as context in evaluating the expression.</param>
        /// <param name="targetType">Type to which the result value is expected to conform.</param>
        /// <returns>The value that results from evaluating the expression in the context of the supplied value, asserted to be of the targetType.</returns>
        public T EvaluateToClrValue <T>(IEdmExpression expression, IEdmStructuredValue context, IEdmTypeReference targetType)
        {
            IEdmValue edmValue = this.Evaluate(expression, context, targetType);

            return(this.edmToClrConverter.AsClrValue <T>(edmValue));
        }
Пример #36
0
        private IEdmDelayedValue MapLabeledExpressionToDelayedValue(IEdmExpression expression, DelayedExpressionContext delayedContext, IEdmStructuredValue context)
        {
            //// Labeled expressions map to delayed values either at the point of definition or at a point of reference
            //// (evaluation of a LabeledExpressionReference that refers to the expression). All of these must map to
            //// a single delayed value (so that the value itself is evaluated only once).

            IEdmLabeledExpression labeledExpression = expression as IEdmLabeledExpression;

            if (labeledExpression == null)
            {
                //// If an expression has no label, there can be no references to it and so only the point of definition needs a mapping to a delayed value,
                //// and so there is no need to cache the delayed value. The point of definition always supplies a context.

                System.Diagnostics.Debug.Assert(delayedContext != null, "Labeled element definition failed to supply an evaluation context.");
                return(new DelayedCollectionElement(delayedContext, expression));
            }

            DelayedValue expressionValue;

            if (this.labeledValues.TryGetValue(labeledExpression, out expressionValue))
            {
                return(expressionValue);
            }

            expressionValue = new DelayedCollectionElement(delayedContext ?? new DelayedExpressionContext(this, context), labeledExpression.Expression);
            this.labeledValues[labeledExpression] = expressionValue;
            return(expressionValue);
        }
Пример #37
0
        /// <summary>
        /// Evaluates an expression in the context of a value.
        /// </summary>
        /// <typeparam name="T">The CLR type of the value to be returned.</typeparam>
        /// <param name="expression">Expression to evaluate.</param>
        /// <param name="context">Value to use as context in evaluating the expression.</param>
        /// <returns>The value that results from evaluating the expression in the context of the supplied value.</returns>
        public T EvaluateToClrValue <T>(IEdmExpression expression, IEdmStructuredValue context)
        {
            IEdmValue edmValue = this.Evaluate(expression, context);

            return(this.edmToClrConverter.AsClrValue <T>(edmValue));
        }
Пример #38
0
 public DelayedExpressionContext(EdmExpressionEvaluator expressionEvaluator, IEdmStructuredValue context)
 {
     this.expressionEvaluator = expressionEvaluator;
     this.context             = context;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ConventionalODataEntityMetadataBuilder"/> class.
 /// </summary>
 /// <param name="baseUri">The base URI of the service.</param>
 /// <param name="entitySetName">Name of the entity set the entity belongs to.</param>
 /// <param name="entityInstance">The entity instance to build metadata for.</param>
 /// <param name="conventions">The user-specified conventions to use.</param>
 internal ConventionalODataEntityMetadataBuilder(Uri baseUri, string entitySetName, IEdmStructuredValue entityInstance, DataServiceUrlConventions conventions)
     : this(UriResolver.CreateFromBaseUri(baseUri, "baseUri"), entitySetName, entityInstance, conventions)
 {
 }
Пример #40
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ConventionalODataEntityMetadataBuilder"/> class.
        /// </summary>
        /// <param name="resolver">The URI resolver to use.</param>
        /// <param name="entitySetName">Name of the entity set the entity belongs to.</param>
        /// <param name="entityInstance">The entity instance to build metadata for.</param>
        /// <param name="conventions">The user-specified conventions to use.</param>
        internal ConventionalODataEntityMetadataBuilder(UriResolver resolver, string entitySetName, IEdmStructuredValue entityInstance, DataServiceUrlConventions conventions)
        {
            Util.CheckArgumentNullAndEmpty(entitySetName, "entitySetName");
            Util.CheckArgumentNull(entityInstance, "entityInstance");
            Util.CheckArgumentNull(conventions, "conventions");
            this.entitySetName  = entitySetName;
            this.entityInstance = entityInstance;

            this.uriBuilder = new ConventionalODataUriBuilder(resolver, conventions);
            this.baseUri    = resolver.BaseUriOrNull;
        }
Пример #41
0
        private IEdmDelayedValue MapLabeledExpressionToDelayedValue(IEdmExpression expression, EdmExpressionEvaluator.DelayedExpressionContext delayedContext, IEdmStructuredValue context)
        {
            EdmExpressionEvaluator.DelayedValue delayedCollectionElement = null;
            IEdmLabeledExpression edmLabeledExpression = expression as IEdmLabeledExpression;

            if (edmLabeledExpression != null)
            {
                if (!this.labeledValues.TryGetValue(edmLabeledExpression, out delayedCollectionElement))
                {
                    EdmExpressionEvaluator.DelayedExpressionContext delayedExpressionContext  = delayedContext;
                    EdmExpressionEvaluator.DelayedExpressionContext delayedExpressionContext1 = delayedExpressionContext;
                    if (delayedExpressionContext == null)
                    {
                        delayedExpressionContext1 = new EdmExpressionEvaluator.DelayedExpressionContext(this, context);
                    }
                    delayedCollectionElement = new EdmExpressionEvaluator.DelayedCollectionElement(delayedExpressionContext1, edmLabeledExpression.Expression);
                    this.labeledValues[edmLabeledExpression] = delayedCollectionElement;
                    return(delayedCollectionElement);
                }
                else
                {
                    return(delayedCollectionElement);
                }
            }
            else
            {
                return(new EdmExpressionEvaluator.DelayedCollectionElement(delayedContext, expression));
            }
        }
 protected ODataUriBuilderTestsBase()
 {
     this.defaultBaseUri         = new Uri("http://odata.org/base/");
     this.model                  = TestModel.BuildDefaultTestModel();
     this.defaultProductInstance = TestModel.BuildDefaultProductValue(TestModel.GetEntityType(this.model, "TestModel.Product"));
 }
Пример #43
0
        public EvaluationTests()
        {
            const string baseModelCsdl =
@"<Schema Namespace=""foo"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
    <Term Name=""DistantAge"" Type=""Int32"" />
    <Term Name=""NewAge"" Type=""Int32"" />
    <Term Name=""Punning0"" Type=""Boolean"" />
    <Term Name=""Punning1"" Type=""Byte"" />
    <Term Name=""Punning2"" Type=""SByte"" />
    <Term Name=""Punning3"" Type=""Int16"" />
    <Term Name=""Punning4"" Type=""Int32"" />
    <Term Name=""Punning5"" Type=""Collection(Int32)"" />
    <Term Name=""Punning6"" Type=""String"" />
    <Term Name=""Punning7"" Type=""String"" />
    <Term Name=""Punning8"" Type=""foo.Cartoon"" />
    <Term Name=""Punning9"" Type=""foo.Cartoon"" />
    <Term Name=""Punning10"" Type=""foo.RealSponsor"" />
    <Term Name=""Punning11"" Type=""foo.Pet"" />
    <Term Name=""PunningBool1"" Type=""Boolean"" />
    <Term Name=""PunningBool2"" Type=""Boolean"" />
    <Term Name=""PunningBool3"" Type=""Boolean"" />
    <Term Name=""PunningBool4"" Type=""Boolean"" />
    <Term Name=""PunningBool5"" Type=""Boolean"" />
    <Term Name=""PunningBool6"" Type=""Boolean"" />
    <Term Name=""PunningBool7"" Type=""Boolean"" />
    <Term Name=""PunningBool8"" Type=""Boolean"" />
    <Term Name=""PunningBool9"" Type=""Boolean"" />
    <Term Name=""PunningBool10"" Type=""Boolean"" />
    <Term Name=""PunningBool11"" Type=""Boolean"" />
    <Term Name=""Clear0"" Type=""foo.Address"" />
    <Term Name=""Clear1"" Type=""Byte"" />
    <Term Name=""Clear2"" Type=""SByte"" />
    <Term Name=""Clear3"" Type=""Int16"" />
    <Term Name=""Clear4"" Type=""Int32"" />
    <Term Name=""Clear6"" Type=""String"" />
    <Term Name=""Clear7"" Type=""String"" />
    <Term Name=""Clear8"" Type=""foo.Cartoon"" />
    <Term Name=""Clear10"" Type=""foo.RealSponsor"" />
    <Term Name=""Clear11"" Type=""foo.Pet"" />
    <Term Name=""ClearBool0"" Type=""Boolean"" />
    <Term Name=""ClearBool1"" Type=""Boolean"" />
    <Term Name=""ClearBool2"" Type=""Boolean"" />
    <Term Name=""ClearBool3"" Type=""Boolean"" />
    <Term Name=""ClearBool4"" Type=""Boolean"" />
    <Term Name=""ClearBool6"" Type=""Boolean"" />
    <Term Name=""ClearBool7"" Type=""Boolean"" />
    <Term Name=""ClearBool8"" Type=""Boolean"" />
    <Term Name=""ClearBool10"" Type=""Boolean"" />
    <Term Name=""ClearBool11"" Type=""Boolean"" />
    <Term Name=""CoolPersonTerm"" Type=""foo.CoolPerson"" />
    <EntityType Name=""Person"">
        <Key>
            <PropertyRef Name=""Name"" />
        </Key>
        <Property Name=""Name"" Type=""String"" Nullable=""false"" />
        <Property Name=""Birthday"" Type=""DateTimeOffset"" />
        <Property Name=""CoolnessIndex"" Type=""Int32"" />
        <Property Name=""Living"" Type=""Boolean"" />
        <Property Name=""Famous"" Type=""Boolean"" />
        <NavigationProperty Name=""Address"" Type=""foo.Address"" Nullable=""false""  />
    </EntityType>
    <EntityType Name=""LyingPerson"" BaseType=""Edm.TypeTerm"">
        <Property Name=""Handle"" Type=""String"" Nullable=""false"" />
        <Property Name=""FictionalAge"" Type=""Int32"" Nullable=""false"" />
    </EntityType>
    <EntityType Name=""CoolPerson"" BaseType=""Edm.TypeTerm"">
        <Property Name=""Sobriquet"" Type=""String"" Nullable=""false"" />
        <Property Name=""Assessment"" Type=""Int32"" Nullable=""false"" />
        <Property Name=""Street"" Type=""String"" />
    </EntityType>
    <EntityType Name=""Address"">
        <Key>
            <PropertyRef Name=""Number"" />
            <PropertyRef Name=""Street"" />
            <PropertyRef Name=""City"" />
            <PropertyRef Name=""State"" />
        </Key>
        <Property Name=""Number"" Type=""Int32"" Nullable=""false"" />
        <Property Name=""Street"" Type=""String"" Nullable=""false"" />
        <Property Name=""City"" Type=""String"" Nullable=""false"" />
        <Property Name=""State"" Type=""String"" Nullable=""false"" />
    </EntityType>
    <EntityType Name=""Cartoon"">
        <Key>
            <PropertyRef Name=""Lead"" />
        </Key>
        <Property Name=""Lead"" Type=""String"" Nullable=""false"" />
        <Property Name=""Sidekick"" Type=""String"" Nullable=""false"" />
        <NavigationProperty Name=""Sponsor"" Type=""foo.Sponsor"" Nullable=""false"" />
    </EntityType>
    <EntityType Name=""Sponsor"">
        <Key>
            <PropertyRef Name=""Name"" />
        </Key>
        <Property Name=""Name"" Type=""String"" Nullable=""false"" />
    </EntityType>
    <ComplexType Name=""Pet"">
        <Property Name=""Name"" Type=""String"" Nullable=""false"" />
        <Property Name=""Age"" Type=""Int32"" Nullable=""true"" />
        <Property Name=""Toys"" Type=""Collection(String)"" />
    </ComplexType>
    <EntityType Name=""FakeSponsor"" BaseType=""foo.Sponsor"">
        <Property Name=""Secret"" Type=""String"" />
    </EntityType>
    <EntityType Name=""RealSponsor"" BaseType=""foo.Sponsor"">
        <Property Name=""Secret"" Type=""String"" />
    </EntityType>
</Schema>";

            const string builtinFunctionsCsdl =
@"<Schema Namespace=""Functions"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <Function Name=""StringConcat""><ReturnType Type=""String""/>
    <Parameter Name=""String1"" Type=""String"" />
    <Parameter Name=""String2"" Type=""String"" />
  </Function>
  <Function Name=""IntegerToString""><ReturnType Type=""String""/>
    <Parameter Name=""Value"" Type=""Int64"" />
  </Function>
</Schema>";

            IEnumerable<EdmError> errors;
            CsdlReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(baseModelCsdl)) }, out this.baseModel, out errors);
            CsdlReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(builtinFunctionsCsdl)) }, out this.builtInFunctionsModel, out errors);

            IEdmEntityType person = (IEdmEntityType)this.baseModel.FindType("foo.Person");
            IEdmEntityType address = (IEdmEntityType)this.baseModel.FindType("foo.Address");

            EdmPropertyValue address1Number = new EdmPropertyValue("Number", new EdmIntegerConstant(null, 1));
            EdmPropertyValue address1Street = new EdmPropertyValue("Street", new EdmStringConstant(null, "Joey Ramone Place"));
            EdmPropertyValue address1City = new EdmPropertyValue("City", new EdmStringConstant(null, "New York"));
            EdmPropertyValue address1State = new EdmPropertyValue("State", new EdmStringConstant(null, "New York"));
            EdmPropertyValue[] address1Properties = new EdmPropertyValue[] { address1Number, address1Street, address1City, address1State };
            EdmStructuredValue address1Value = new EdmStructuredValue(new EdmEntityTypeReference(address, true), address1Properties);

            EdmPropertyValue person1Name = new EdmPropertyValue("Name", new EdmStringConstant(null, "Joey Ramone"));
            EdmPropertyValue person1Birthday = new EdmPropertyValue("Birthday", new EdmDateTimeOffsetConstant(null, new DateTimeOffset(new DateTime(1951, 5, 19), TimeSpan.Zero)));
            EdmPropertyValue person1CoolnessIndex = new EdmPropertyValue("CoolnessIndex", new EdmIntegerConstant(null, Int32.MaxValue));
            EdmPropertyValue person1Living = new EdmPropertyValue("Living", new EdmBooleanConstant(false));
            EdmPropertyValue person1Famous = new EdmPropertyValue("Famous", new EdmBooleanConstant(null, true));
            EdmPropertyValue person1Address = new EdmPropertyValue("Address", address1Value);

            EdmPropertyValue[] person1Properties = new EdmPropertyValue[] { person1Name, person1Birthday, person1CoolnessIndex, person1Living, person1Famous, person1Address };
            this.personValue = new EdmStructuredValue(new EdmEntityTypeReference(person, false), person1Properties);

            this.builtInFunctions = new Dictionary<IEdmOperation, Func<IEdmValue[], IEdmValue>>();

            IEdmOperation stringConcat = this.builtInFunctionsModel.FindOperations("Functions.StringConcat").Single();
            this.builtInFunctions[stringConcat] = (a) => new EdmStringConstant(((IEdmStringValue)a[0]).Value + ((IEdmStringValue)a[1]).Value);

            IEdmOperation integerToString = this.builtInFunctionsModel.FindOperations("Functions.IntegerToString").Single();
            this.builtInFunctions[integerToString] = (a) => new EdmStringConstant(((IEdmIntegerValue)a[0]).Value.ToString());
        }