Beispiel #1
0
        /// <summary>
        /// Gets the existing values of the given primitive properties using the in-memory query evaluator
        /// </summary>
        /// <param name="set">The entity set</param>
        /// <param name="propertyNames">The properties to get values for</param>
        /// <returns>The values for the given properties as returned by the query evaluator</returns>
        protected internal Dictionary <string, List <object> > GetExistingPrimitivePropertyValues(EntitySet set, IEnumerable <string> propertyNames)
        {
            // build a projection query to find the values for the key properties
            var query = this.BuildRootQueryForSet(set).Select(o => LinqBuilder.New(propertyNames, propertyNames.Select(p => o.Property(p))));

            // evaluate the projection
            var collection = this.Evaluator.Evaluate(query) as QueryCollectionValue;

            ExceptionUtilities.CheckObjectNotNull(collection, "Query did not return a collection: {0}", query);
            ExceptionUtilities.Assert(collection.EvaluationError == null, "Query evaluation error: " + collection.EvaluationError);

            var structuralValues = collection.Elements.Cast <QueryStructuralValue>();
            var existingValues   = propertyNames
                                   .ToDictionary(p => p, p => structuralValues.Select(v => v.GetScalarValue(p).Value).ToList());

            return(existingValues);
        }
        /// <summary>
        /// Finds the structural value for the given serializable entity and updates it, or create it if it does not exist
        /// </summary>
        /// <param name="baseType">The base type of the entity's set</param>
        /// <param name="entity">The entity to find and synchronize</param>
        /// <param name="existingEntityGraph">The existing entities in the set, mapped by key</param>
        /// <returns>The synchronized entity</returns>
        private QueryStructuralValue FindAndSynchronizeEntity(QueryEntityType baseType, SerializableEntity entity, IDictionary <EntityDataKey, QueryStructuralValue> existingEntityGraph)
        {
            QueryStructuralValue alreadySynchronized;

            if (this.synchronizationCache.TryGetValue(entity, out alreadySynchronized))
            {
                return(alreadySynchronized);
            }

            // if the type does not match, it must be a derived type
            var type = baseType;

            if (type.EntityType.FullName != entity.EntityType)
            {
                type = type.DerivedTypes.Cast <QueryEntityType>().SingleOrDefault(t => t.EntityType.FullName == entity.EntityType);
                ExceptionUtilities.CheckObjectNotNull(type, "Could not find a type named '{0}'", entity.EntityType);
            }

            // compute the key for the entity
            var key = this.GetEntityKey(type, entity);
            QueryStructuralValue structural;
            bool isNewInstance = !existingEntityGraph.TryGetValue(key, out structural);

            // if we don't find it, create it
            if (isNewInstance)
            {
                structural = type.CreateNewInstance();
                InitMemberStreamTypes(type, structural);
            }

            this.synchronizationCache[entity] = structural;
            this.SynchronizeProperties(baseType, entity, type, structural, existingEntityGraph);
            this.SynchronizeStreams(entity, structural);

            structural.MarkDynamicPropertyValues();

            // if its a new instance, add it to the top-level collection
            if (isNewInstance)
            {
                this.QueryDataSet[type.EntitySet.Name].Elements.Add(structural);
                existingEntityGraph[this.GetEntityKey(structural)] = structural;
            }

            return(structural);
        }
        /// <summary>
        /// Tries to get next data to upload.
        /// </summary>
        /// <param name="data">The data to upload.</param>
        /// <returns>True if there is a data for upload, false otherwise.</returns>
        public virtual bool TryPopulateNextData(out EntityContainerData data)
        {
            ExceptionUtilities.CheckObjectNotNull(this.StructuralDataServices, "StructuralGenerators cannot be null.");

            this.CreateEntitySetAndTypeSelectorIfNull();
            this.CreateRelationshipSelectorsIfNull();

            if (this.seedData != null)
            {
                data          = this.seedData;
                this.seedData = null;
            }
            else
            {
                data = new EntityContainerData(this.EntityContainer);
            }

            int createdEntitiesCount = 0, createdAssociationsCount = 0;

            this.CreateRelationships(data, ref createdEntitiesCount, ref createdAssociationsCount);

            EntitySet  entitySet;
            EntityType entityType;

            while (this.GetNextEntitySetAndTypeToCreate(out entitySet, out entityType))
            {
                EntitySetDataRow row = this.PopulateNewEntitySetRow(data, entitySet, entityType);
                createdEntitiesCount++;
                this.ConsiderCandidateForRelationships(row);

                this.CreateRelationships(data, ref createdEntitiesCount, ref createdAssociationsCount);

                if (createdEntitiesCount >= this.ThresholdForNumberOfEntities && this.ThresholdForNumberOfEntities != -1)
                {
                    break;
                }
            }

            if (this.ReferentialConstraintsResolver != null)
            {
                this.ReferentialConstraintsResolver.ResolveReferentialConstraints(data);
            }

            return(createdEntitiesCount > 0 || createdAssociationsCount > 0);
        }
        private void BuildStructuralPropertiesQueryValue(QueryStructuralValue instance, string propertyPath, IList <MemberProperty> properties, IList <QueryProperty> queryProperties, EntitySetDataRow row)
        {
            ExceptionUtilities.Assert(properties.Count == queryProperties.Count, "QueryProperties '{0}' and MemberProperties '{1}' are not the same number!", CreateQueryPropertyList(queryProperties), CreateMemberPropertyList(properties));

            // TODO: Some Taupo framework pieces skip over StreamDataType properties
            foreach (MemberProperty childProperty in properties.Where(p => !(p.PropertyType is StreamDataType)))
            {
                string childPropertyPath = propertyPath + childProperty.Name;
                List <QueryProperty> childQueryProperties = queryProperties.Where(p => p.Name == childProperty.Name).ToList();
                ExceptionUtilities.Assert(childQueryProperties.Count == 1, "Could not find query property based on MemberProperty Name '{0}' in list of query properties '{1}'", childProperty.Name, CreateQueryPropertyList(childQueryProperties));

                QueryProperty childQueryProperty = childQueryProperties.First();

                QueryCollectionType childCollectionDataType = childQueryProperty.PropertyType as QueryCollectionType;
                QueryScalarType     childScalarType         = childQueryProperty.PropertyType as QueryScalarType;
                QueryComplexType    childComplexType        = childQueryProperty.PropertyType as QueryComplexType;

                if (childCollectionDataType != null)
                {
                    instance.SetValue(childProperty.Name, this.BuildCollectionQueryValue(childPropertyPath + ".", childCollectionDataType, row));
                }
                else if (childScalarType != null)
                {
                    var value      = row[childPropertyPath];
                    var queryValue = childScalarType.CreateValue(value);
                    instance.SetValue(childQueryProperty.Name, queryValue);
                }
                else
                {
                    ExceptionUtilities.CheckObjectNotNull(childComplexType, "Unknown type '{0}'", childProperty.PropertyType);

                    // If a complex type instance is null in the datarow, we will create a QueryStructuralValue indicating null and set it on the instance.
                    if (row.PropertyPaths.Contains(childPropertyPath) && row[childPropertyPath] == null)
                    {
                        instance.SetValue(childProperty.Name, new QueryStructuralValue(childComplexType, true, null, childComplexType.EvaluationStrategy));
                    }
                    else
                    {
                        QueryStructuralValue childInstance = childComplexType.CreateNewInstance();
                        this.BuildStructuralPropertiesQueryValue(childInstance, childPropertyPath + ".", childComplexType.ComplexType.Properties, childComplexType.Properties, row);
                        instance.SetValue(childProperty.Name, childInstance);
                    }
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Applies EPM mapping to the specified entity type on the model and returns it for composablity.
        /// </summary>
        /// <param name="model">Model to use</param>
        /// <param name="entityTypeName">Entity type name</param>
        /// <param name="sourcePath">Source path</param>
        /// <param name="targetSyndicationItem">TargetSyndicationItem to use</param>
        /// <param name="targetTextContentKind">TargetTextContentKind to use</param>
        /// <param name="keepInContent">true to keep the mapped value in content; otherwise false (defaults to true).</param>
        /// <returns>Enity Model Schema with the mapping applied</returns>
        public static EntityModelSchema EntityPropertyMapping(
            this EntityModelSchema model,
            string entityTypeName,
            string sourcePath,
            SyndicationItemProperty targetSyndicationItem    = SyndicationItemProperty.AuthorName,
            SyndicationTextContentKind targetTextContentKind = SyndicationTextContentKind.Plaintext,
            bool keepInContent = true)
        {
            ExceptionUtilities.CheckArgumentNotNull(model, "model");
            ExceptionUtilities.CheckArgumentNotNull(entityTypeName, "entityTypeName");
            ExceptionUtilities.CheckArgumentNotNull(sourcePath, "sourcePath");
            var entityType = model.GetEntityType(entityTypeName);

            ExceptionUtilities.CheckObjectNotNull(entityType, "There are no entity types matching the name:{0} in the model", entityTypeName);
            entityType.EntityPropertyMapping(sourcePath, targetSyndicationItem, targetTextContentKind, keepInContent);

            return(model);
        }
        /// <summary>
        /// Serializes the given root element to a binary representation
        /// </summary>
        /// <param name="rootElement">The root element, must be a primitive value with either a null or binary value</param>
        /// <param name="encodingName">Optional name of an encoding to use if it is relevant to the current format. May be null if no character-set information was known.</param>
        /// <returns>The serialized value</returns>
        public override byte[] SerializeToBinary(ODataPayloadElement rootElement, string encodingName)
        {
            ExceptionUtilities.CheckArgumentNotNull(rootElement, "rootElement");
            ExceptionUtilities.Assert(rootElement.ElementType == ODataPayloadElementType.PrimitiveValue, "Only primitive values can be serialized as raw values. Type was: {0}", rootElement.ElementType);

            var value = (rootElement as PrimitiveValue).ClrValue;

            if (value == null)
            {
                return(new byte[0]);
            }

            var binary = value as byte[];

            ExceptionUtilities.CheckObjectNotNull(binary, "Payload element was not a binary value");

            return(binary);
        }
        /// <summary>
        /// Verifies the update succeeded
        /// </summary>
        /// <param name="request">The request to verify</param>
        /// <param name="response">The response to verify</param>
        public override void Verify(ODataRequest request, ODataResponse response)
        {
            var functionSegment = request.Uri.LastSegment as FunctionSegment;

            ExceptionUtilities.CheckObjectNotNull(functionSegment, "Expected a Uri with a FunctionSegment at the end");
            ExceptionUtilities.CheckObjectNotNull(functionSegment.Function, "Expected a FunctionSegment to have a valid Function");
            ExceptionUtilities.Assert(functionSegment.Function.IsAction(), "Expected a FunctionSegment that is an action");

            var dataServiceMemberGeneratorAnnotation = functionSegment.Function.Annotations.OfType <DataServiceMemberGeneratorAnnotation>().SingleOrDefault();
            var verifyServiceQueryResult             = dataServiceMemberGeneratorAnnotation as IVerifyServiceActionQueryResult;
            var throwErrorAnnotation = functionSegment.Function.Annotations.OfType <ThrowDataServiceExceptionAnnotation>().SingleOrDefault();

            // TODO: add verification of the thrown error case, will add later
            if (throwErrorAnnotation == null && verifyServiceQueryResult != null)
            {
                this.VerifyQueryResult(request, response, functionSegment, verifyServiceQueryResult);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Converts the given segment into a string
        /// </summary>
        /// <param name="segment">The segment to convert</param>
        /// <returns>The converted segment string</returns>
        public string ConvertToString(EntitySetSegment segment)
        {
            ExceptionUtilities.CheckArgumentNotNull(segment, "segment");
            ExceptionUtilities.CheckObjectNotNull(segment.EntitySet != null || segment.EdmEntitySet != null, "Segment's entity set was unexpectedly null");

            if (segment.EntitySet != null)
            {
                ExceptionUtilities.CheckObjectNotNull(segment.EntitySet.Container, "Segment's entity set's container was unexpectedly null");

                return(this.EscapeUriString(segment.EntitySet.Name));
            }
            else
            {
                ExceptionUtilities.CheckObjectNotNull(segment.EdmEntitySet.Container, "Segment's entity set's container was unexpectedly null");

                return(this.EscapeUriString(segment.EdmEntitySet.Container.Name + '.' + segment.EdmEntitySet.Name));
            }
        }
        private QueryValue SynchronizeAndEvaluate(ODataUri entityUri, QueryStructuralValue beforeSync, bool synchronizeEntireSet)
        {
            var entityType = beforeSync.Type as QueryEntityType;

            ExceptionUtilities.CheckObjectNotNull(entityType, "Structural value was not an entity type");

            // if an entity was deleted, synchronize the entire set. Otherwise just synchronize the entity
            if (synchronizeEntireSet)
            {
                SyncHelpers.ExecuteActionAndWait(c => this.Synchronizer.SynchronizeEntireEntitySet(c, entityType.EntitySet.Name));
            }
            else
            {
                SyncHelpers.ExecuteActionAndWait(c => this.Synchronizer.SynchronizeEntity(c, beforeSync));
            }

            return(this.Evaluator.Evaluate(entityUri, false, false));
        }
        private ChangeData CreateChangeData(DescriptorData descriptorData, IDictionary <object, IEnumerable <NamedValue> > propertyValuesBeforeSave)
        {
            var entityDescriptorData = descriptorData as EntityDescriptorData;

            if (entityDescriptorData != null)
            {
                IEnumerable <NamedValue> propertyValues;
                ExceptionUtilities.Assert(propertyValuesBeforeSave.TryGetValue(entityDescriptorData.Entity, out propertyValues), "Could not find property values for descriptor: {0}", entityDescriptorData);

                return(EntityChangeData.Create(entityDescriptorData, propertyValues));
            }

            var linkDescriptorData = descriptorData as LinkDescriptorData;

            ExceptionUtilities.CheckObjectNotNull(linkDescriptorData, "Descriptor was neither an entity nor a link");

            return(LinkChangeData.Create(linkDescriptorData));
        }
Beispiel #11
0
        /// <summary>
        /// Gets the method handle for a method with a given generic signature.
        /// </summary>
        /// <param name="type">The type (definition in case of generics).</param>
        /// <param name="signature">The signature of the method.</param>
        /// <returns>Method info.</returns>
        public static MethodInfo GetMethodInfo(Type type, string signature)
        {
            ExceptionUtilities.CheckObjectNotNull(PlatformMethodMap, "Platform method map was not initialized");
            if (PlatformMethodMap.ContainsKey(signature))
            {
                signature = PlatformMethodMap[signature];
            }

            foreach (var method in type.GetMethods())
            {
                if (MethodMatches(signature, method))
                {
                    return(method);
                }
            }

            throw new TaupoInvalidOperationException("Could not find method matching signature: '" + signature + "'.");
        }
Beispiel #12
0
        /// <summary>
        /// Converts specified data generation hint into Xml.
        /// </summary>
        /// <param name="hint">The data generation hint to convert.</param>
        /// <returns>Xml representation of the data generation hint.</returns>
        public static XElement ToXml(DataGenerationHint hint)
        {
            Type hintType = hint.GetType();

            string key = GetHintKey(hintType);

            if (hint is SingletonDataGenerationHint)
            {
                return(new XElement(key));
            }

            PropertyInfo valuePropertyInfo = hintType.GetProperty("Value");

            ExceptionUtilities.CheckObjectNotNull(valuePropertyInfo, "Unsupported data generation hint type: '{0}'.", hintType.FullName);
            object value = valuePropertyInfo.GetValue(hint, null);

            return(new XElement(key, new XAttribute(ValueAttributeName, value)));
        }
Beispiel #13
0
 private void GetUpdatedEntityBeforeAndAfter(ODataRequest request, ODataResponse response, out QueryStructuralValue beforeUpdate, out QueryStructuralValue afterUpdate)
 {
     using (this.Context.Begin(request))
     {
         if (request.GetEffectiveVerb() == HttpVerb.Post)
         {
             afterUpdate = this.Context.GetInsertedEntity(request, response);
             ExceptionUtilities.CheckObjectNotNull(afterUpdate, "Structural value returned by GetInsertedEntity unexpectedly null");
             beforeUpdate = afterUpdate.Type.NullValue;
         }
         else
         {
             this.Context.GetUpdatedEntity(request, out beforeUpdate, out afterUpdate);
             ExceptionUtilities.CheckObjectNotNull(beforeUpdate, "Before-update structural value returned by GetUpdatedEntity unexpectedly null");
             ExceptionUtilities.CheckObjectNotNull(afterUpdate, "After-update structural value returned by GetUpdatedEntity unexpectedly null");
         }
     }
 }
Beispiel #14
0
        /// <summary>
        /// Gets the entity inserted by the given request.
        /// </summary>
        /// <param name="request">The request</param>
        /// <param name="response">The response</param>
        /// <returns>The inserted entity</returns>
        public QueryStructuralValue GetInsertedEntity(ODataRequest request, ODataResponse response)
        {
            ExceptionUtilities.CheckArgumentNotNull(request, "request");
            ExceptionUtilities.CheckArgumentNotNull(response, "response");
            ExceptionUtilities.Assert(this.requestsBegun.Contains(request), "Cannot use GetInsertedEntity before calling Begin");
            ExceptionUtilities.Assert(request.GetEffectiveVerb() == HttpVerb.Post, "Cannot use GetInsertedEntity on non POST requests");

            QueryStructuralValue insertedEntity;

            if (!this.insertedEntityCache.TryGetValue(request, out insertedEntity))
            {
                EntitySet entitySet;
                ExceptionUtilities.Assert(request.Uri.TryGetExpectedEntitySet(out entitySet), "Could not infer entity set from URI");

                var entitySetUri = new ODataUri(new EntitySetSegment(entitySet));

                var beforeSync = this.Evaluator.Evaluate(entitySetUri, false, false) as QueryCollectionValue;
                ExceptionUtilities.CheckObjectNotNull(beforeSync, "Could not evaluate entity set '{0}' before syncing", entitySet.Name);

                // create a shallow copy
                beforeSync = beforeSync.Type.CreateCollectionWithValues(beforeSync.Elements);

                SyncHelpers.ExecuteActionAndWait(c => this.Synchronizer.SynchronizeEntireEntitySet(c, entitySet.Name));

                var afterSync = this.Evaluator.Evaluate(entitySetUri, false, false) as QueryCollectionValue;
                ExceptionUtilities.CheckObjectNotNull(afterSync, "Could not evaluate entity set '{0}' after syncing", entitySet.Name);

                // TODO: handle deep insert (using location header or response payload)
                var newElements = afterSync.Elements.Except(beforeSync.Elements).OfType <QueryStructuralValue>().ToList();
                this.insertedEntityCache[request] = insertedEntity = newElements.Single();

                // update the parent entity, if there is one
                var segments = request.Uri.Segments;
                var lastNavigationSegment = segments.OfType <NavigationSegment>().LastOrDefault();
                if (lastNavigationSegment != null)
                {
                    var segmentsBeforeNavigation = segments.TakeWhile(t => t != lastNavigationSegment);
                    var parentEntity             = (QueryStructuralValue)this.Evaluator.Evaluate(new ODataUri(segmentsBeforeNavigation), false, false);
                    SyncHelpers.ExecuteActionAndWait(c => this.Synchronizer.SynchronizeEntity(c, parentEntity));
                }
            }

            return(insertedEntity);
        }
Beispiel #15
0
        private void VerifyDescriptor(DescriptorData expected, Descriptor actual, int responseOrder)
        {
            EntityDescriptorData entityDescriptorData = expected as EntityDescriptorData;
            LinkDescriptorData   linkDescriptorData   = expected as LinkDescriptorData;
            StreamDescriptorData streamDescriptorData = expected as StreamDescriptorData;

            if (entityDescriptorData != null)
            {
                EntityDescriptor entityDescriptor = actual as EntityDescriptor;
                this.Assert.IsNotNull(entityDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual:   {1}\r\nExpected descriptor data: {2}.", typeof(EntityDescriptor).Name, actual.GetType().Name, entityDescriptorData));

                this.Assert.AreSame(
                    entityDescriptorData.Entity,
                    entityDescriptor.Entity,
                    GetVerificationFailureMessage(responseOrder, "Entity verification failed for the entity descriptor data: {0}.", expected));
            }
            else if (linkDescriptorData != null)
            {
                LinkDescriptor linkDescriptor = actual as LinkDescriptor;
                this.Assert.IsNotNull(linkDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual:   {1}\r\nExpected descriptor data: {2}.", typeof(LinkDescriptor).Name, actual.GetType().Name, linkDescriptorData));

                bool notMatch = linkDescriptorData.SourceDescriptor.Entity != linkDescriptor.Source ||
                                (linkDescriptorData.TargetDescriptor == null && linkDescriptor.Target != null) ||
                                (linkDescriptorData.TargetDescriptor != null && linkDescriptorData.TargetDescriptor.Entity != linkDescriptor.Target) ||
                                linkDescriptorData.SourcePropertyName != linkDescriptor.SourceProperty;

                this.Assert.IsFalse(notMatch, GetVerificationFailureMessage(responseOrder, "Link verification failed.\r\nExpected: {0}\r\nActual:   {1}", linkDescriptorData, linkDescriptor.ToTraceString()));
            }
            else
            {
                ExceptionUtilities.CheckObjectNotNull(streamDescriptorData, "Expected was not an entity, link, or stream descriptor: {0}", expected);

                StreamDescriptor streamDescriptor = actual as StreamDescriptor;

                this.Assert.IsNotNull(streamDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual:   {1}\r\nExpected descriptor data: {2}.", typeof(StreamDescriptor).Name, actual.GetType().Name, streamDescriptorData));

                this.Assert.AreEqual(streamDescriptorData.State.ToProductEnum(), streamDescriptor.State, GetVerificationFailureMessage(responseOrder, "Stream descriptor state verification failed."));
                this.Assert.AreEqual(streamDescriptorData.Name, streamDescriptor.StreamLink.Name, GetVerificationFailureMessage(responseOrder, "Stream descriptor name verification failed."));
                this.Assert.AreEqual(streamDescriptorData.ETag, streamDescriptor.StreamLink.ETag, GetVerificationFailureMessage(responseOrder, "Stream descriptor etag verification failed."));
                this.Assert.AreEqual(streamDescriptorData.ContentType, streamDescriptor.StreamLink.ContentType, GetVerificationFailureMessage(responseOrder, "Stream descriptor content type verification failed."));
                this.Assert.AreEqual(streamDescriptorData.EditLink, streamDescriptor.StreamLink.EditLink, GetVerificationFailureMessage(responseOrder, "Stream descriptor edit link verification failed."));
                this.Assert.AreEqual(streamDescriptorData.SelfLink, streamDescriptor.StreamLink.SelfLink, GetVerificationFailureMessage(responseOrder, "Stream descriptor self link verification failed."));
            }
        }
Beispiel #16
0
        private void SetDataFromPropertyInfo(object item, PropertyInfo propertyInfo, MemberProperty memberProperty, string currentPath)
        {
            object propertyValue = propertyInfo.GetValue(item, null);

            if (memberProperty.PropertyType is PrimitiveDataType || memberProperty.PropertyType is EnumDataType)
            {
                this[currentPath + memberProperty.Name] = propertyValue;
            }
            else if (memberProperty.PropertyType is ComplexDataType)
            {
                this.ImportFrom(propertyValue, currentPath + memberProperty.Name, (memberProperty.PropertyType as ComplexDataType).Definition);
            }
            else
            {
                var collectionDataType = memberProperty.PropertyType as CollectionDataType;
                ExceptionUtilities.Assert(collectionDataType != null, "Only properties with primitive, complex, or collection of primitive and complex data types are supported. Property: '{0}', type: '{1}'.", memberProperty.Name, memberProperty.PropertyType);

                var primitiveElementDataType = collectionDataType.ElementDataType as PrimitiveDataType;
                var complexElementDataType   = collectionDataType.ElementDataType as ComplexDataType;

                ExceptionUtilities.CheckObjectNotNull(propertyValue, "Collection Property MUST not be Null at PropertyPath '{0}'", currentPath + memberProperty.Name);
                var enumerableItem = propertyValue as IEnumerable;
                ExceptionUtilities.CheckObjectNotNull(enumerableItem, "propertyValue should be IEnumerable but is not, its type is '{0};", propertyValue.GetType().Name);
                if (primitiveElementDataType != null)
                {
                    int i = 0;
                    foreach (object o in enumerableItem)
                    {
                        this[currentPath + memberProperty.Name + "." + i] = o;
                        i++;
                    }
                }
                else
                {
                    ExceptionUtilities.Assert(complexElementDataType != null, "ElementType {0} of CollectionType Property is not supported", collectionDataType.ElementDataType);
                    int i = 0;
                    foreach (object o in enumerableItem)
                    {
                        this.ImportFrom(o, currentPath + memberProperty.Name + "." + i, complexElementDataType.Definition);
                        i++;
                    }
                }
            }
        }
Beispiel #17
0
        /// <summary>
        /// Evaluates member property of a spatial instance.
        /// </summary>
        /// <param name="instance">The instance of query value object</param>
        /// <param name="resultType">The property result type.</param>
        /// <param name="memberPropertyName">The member property name to evaluate.</param>
        /// <returns>
        /// Query value which is the result of method evaluation.
        /// </returns>
        public override QueryValue EvaluateMemberProperty(QueryValue instance, QueryType resultType, string memberPropertyName)
        {
            if (this.IsSpatialType((IQueryClrType)instance.Type))
            {
                var clrInstance = ((QueryScalarValue)instance).Value;
                if (clrInstance == null)
                {
                    var nullValue = resultType.NullValue;
                    nullValue.EvaluationError = new QueryError("Cannot access member property on a null instance");
                    return(nullValue);
                }

                var clrType = clrInstance.GetType();
                while (!clrType.IsPublic())
                {
                    clrType = clrType.GetBaseType();
                }

                var property = clrType.GetProperty(memberPropertyName, true, false);
                ExceptionUtilities.CheckObjectNotNull(property, "Could not find property");

                var propertyValue = property.GetValue(clrInstance, null);
                if (propertyValue == null)
                {
                    return(resultType.NullValue);
                }

                var collectionType = resultType as QueryCollectionType;
                if (collectionType != null)
                {
                    var enumerable = propertyValue as IEnumerable;
                    ExceptionUtilities.CheckObjectNotNull(enumerable, "Collection value must be ienumerable. Value was '{0}'", propertyValue);

                    var elementType = (QueryScalarType)collectionType.ElementType;
                    return(collectionType.CreateCollectionWithValues(enumerable.Cast <object>().Select(o => (QueryValue)elementType.CreateValue(o))));
                }
                else
                {
                    return(((QueryScalarType)resultType).CreateValue(propertyValue));
                }
            }

            return(base.EvaluateMemberProperty(instance, resultType, memberPropertyName));
        }
Beispiel #18
0
        private void ProcessEntityAndGenerateStreams(QueryStructuralValue queryStructuralValue, IAsyncContinuation continuation, HttpWebResponse response)
        {
            ExceptionUtilities.Assert(response.StatusCode == HttpStatusCode.OK, "Error generating stream data, response code incorrect:" + response.StatusCode.ToString());
            var responseValue = new StreamReader(response.GetResponseStream()).ReadToEnd();

            try
            {
                var existingEntityInXML = XElement.Parse(responseValue);
                var feedInstance        = this.XmlToPayloadConverter.ConvertToPayloadElement(existingEntityInXML) as EntitySetInstance;
                ExceptionUtilities.CheckObjectNotNull(feedInstance, "Error generating stream data, cannot deserialize response:" + existingEntityInXML);

                var type = queryStructuralValue.Type as QueryEntityType;
                ExceptionUtilities.CheckObjectNotNull(type, "Type was not an entity type. Type was {0}", type.StringRepresentation);

                Func <AstoriaQueryStreamValue, bool> valueFilter    = v => v.IsNull || v.Value.Length == 0;
                Func <QueryProperty, bool>           propertyFilter = p => p.IsStream() && valueFilter(queryStructuralValue.GetStreamValue(p.Name));
                var streamPropertiesToUpdate = type.Properties.Where(propertyFilter).ToList();

                if (feedInstance.Count != 0)
                {
                    var entityInstance = feedInstance.SingleOrDefault();
                    ExceptionUtilities.CheckObjectNotNull(entityInstance, "Payload did not contain a single entity instance");

                    var baseAddressAnnotation = feedInstance.Annotations.OfType <XmlBaseAnnotation>().SingleOrDefault();

                    foreach (var streamProperty in streamPropertiesToUpdate)
                    {
                        var streamPropertyType = streamProperty.PropertyType as AstoriaQueryStreamType;
                        ExceptionUtilities.CheckObjectNotNull(streamPropertyType, "PropertyType is not an AstoriaQueryStreamType!", streamProperty.PropertyType);

                        var streamData = this.GenerateStreamData(entityInstance, baseAddressAnnotation, streamProperty);
                        this.streamsToUpdate.Add(streamData);
                    }
                }

                continuation.Continue();
            }
            catch (XmlException)
            {
                this.Logger.WriteLine(LogLevel.Error, "Error in Xml payload:" + responseValue);

                throw;
            }
        }
Beispiel #19
0
        private TestCase InvokeMatrixCombinationCallback(Type type, TestCase testCase, TestCaseAttribute attribute)
        {
            var callbackAttr = (TestMatrixCombinationCallbackAttribute)type.GetCustomAttributes(typeof(TestMatrixCombinationCallbackAttribute), false).SingleOrDefault();

            if (callbackAttr != null)
            {
                var callbackMethod = type.GetMethod(callbackAttr.CallbackMethodName, true, true);
                ExceptionUtilities.CheckObjectNotNull(callbackMethod, "Could not find static method '{0}' on type '{1}'", callbackAttr.CallbackMethodName, type);
                ExceptionUtilities.Assert(typeof(TestCase).IsAssignableFrom(callbackMethod.ReturnType), "Matrix combination callback '{0}' returns unexpected type '{1}'", callbackMethod.Name, callbackMethod.ReturnType);

                var arguments = new object[attribute.Parameters.Length + 1];
                arguments[0] = testCase;
                Array.Copy(attribute.Parameters, 0, arguments, 1, attribute.Parameters.Length);

                testCase = (TestCase)callbackMethod.Invoke(null, arguments);
            }

            return(testCase);
        }
Beispiel #20
0
        private VariationTestItem InvokeMatrixCombinationCallback(MethodInfo method, VariationTestItem variation, VariationAttribute attribute)
        {
            var callbackAttr = (TestMatrixCombinationCallbackAttribute)method.GetCustomAttributes(typeof(TestMatrixCombinationCallbackAttribute), false).SingleOrDefault();

            if (callbackAttr != null)
            {
                var callbackMethod = this.GetType().GetMethod(callbackAttr.CallbackMethodName, true, false);
                ExceptionUtilities.CheckObjectNotNull(callbackMethod, "Could not find instance method '{0}' on type '{1}'", callbackAttr.CallbackMethodName, this.GetType());
                ExceptionUtilities.Assert(typeof(VariationTestItem).IsAssignableFrom(callbackMethod.ReturnType), "Matrix combination callback '{0}' returns unexpected type '{1}'", callbackMethod.Name, callbackMethod.ReturnType);

                var arguments = new object[attribute.Parameters.Length + 1];
                arguments[0] = variation;
                Array.Copy(attribute.Parameters, 0, arguments, 1, attribute.Parameters.Length);

                variation = (VariationTestItem)callbackMethod.Invoke(this, arguments);
            }

            return(variation);
        }
Beispiel #21
0
        /// <summary>
        /// Gets the type for a given name of the type.
        /// </summary>
        /// <param name="typeName">Name of the type.</param>
        /// <param name="assemblyName">Name of the assembly.</param>
        /// <returns>The requested type.</returns>
        public static Type GetTypeFromAssembly(string typeName, string assemblyName)
        {
            Type type = null;

            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (assembly.FullName.Substring(0, assembly.FullName.IndexOf(",", StringComparison.Ordinal)) == assemblyName)
                {
                    type = assembly.GetType(typeName);
                    if (type != null)
                    {
                        break;
                    }
                }
            }

            ExceptionUtilities.CheckObjectNotNull(type, "Type {0} not found", typeName);
            return(type);
        }
Beispiel #22
0
        /// <summary>
        /// Uses the given target type to invoke the appropriate deserialize method
        /// Throws if the given type is not valid
        /// </summary>
        /// <param name="value">The wire representation of a primitive value</param>
        /// <param name="targetType">The type to deserialize into</param>
        /// <returns>A clr instance of the primitive value</returns>
        public virtual object DeserializePrimitive(TWire value, Type targetType)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetType, "targetType");

            bool nullableType = false;

            // if its nullable, just get the generic argument
            if (targetType.IsGenericType() &&
                targetType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                nullableType = true;
                targetType   = Nullable.GetUnderlyingType(targetType);
            }

            if ((nullableType || !targetType.IsValueType()) && this.ValueIsNull(value, targetType))
            {
                return(null);
            }

            // find a method with the right return type and a single parameter of type TWire
            MethodInfo method = typeof(PrimitiveConverter <TWire>).GetMethods()
                                .SingleOrDefault(m => m.ReturnType == targetType &&
                                                 m.Name.StartsWith("Deserialize", StringComparison.Ordinal) &&
                                                 m.GetParameters().Count(p => p.ParameterType == typeof(TWire)) == 1);

            ExceptionUtilities.CheckObjectNotNull(method, "Cannot deserialize into target type '{0}'", targetType.FullName);

            // invoke the method
            object result = method.Invoke(this, new object[] { value });

            // ensure its of the right type before returning it
            ExceptionUtilities.Assert(targetType.IsInstanceOfType(result), "Result of deserialization was not of expected type");

            if (nullableType)
            {
                Type            nullable    = typeof(Nullable <>).MakeGenericType(targetType);
                ConstructorInfo constructor = nullable.GetInstanceConstructor(true, new Type[] { targetType });
                ExceptionUtilities.CheckObjectNotNull(constructor, "Cannot find constructor for Nullable<> with type argument: " + targetType.FullName);
                result = constructor.Invoke(new object[] { result });
            }

            return(result);
        }
Beispiel #23
0
        protected override void VisitResponseOperation(HttpResponseData operation)
        {
            var responseOperation = operation as ODataResponse;

            ExceptionUtilities.CheckObjectNotNull(responseOperation, "Operation must be a response");
            ODataPayloadElement rootElement = null;
            string contentType = null;

            if (responseOperation.RootElement != null)
            {
                rootElement = responseOperation.RootElement;
                contentType = responseOperation.GetHeaderValueIfExists(Microsoft.OData.ODataConstants.ContentTypeHeader);
            }
            if (rootElement != null)
            {
                this.resolver.ResolveMetadata(rootElement, this.BuildODataUri(rootElement));
                this.selector.GetNormalizer(contentType);
            }
        }
        private IEdmVocabularyAnnotatable ConvertToStockVocabularyAnnotatable(IEdmElement edmAnnotatable, EdmModel stockModel)
        {
            // TODO: Need to provide a better way to get more details on IEdmVocabularyAnnotation.Target.
            IEdmVocabularyAnnotatable stockAnnotatable = null;

            if (edmAnnotatable is IEdmEntityType)
            {
                var edmEntityType = edmAnnotatable as IEdmEntityType;
                stockAnnotatable = stockModel.FindType(edmEntityType.FullName()) as IEdmVocabularyAnnotatable;
                ExceptionUtilities.CheckObjectNotNull(stockAnnotatable, "The FindType method must be successful.");
            }
            else if (edmAnnotatable is IEdmProperty)
            {
                var edmProperty = edmAnnotatable as IEdmProperty;
                if (edmProperty.DeclaringType is IEdmSchemaElement)
                {
                    var stockSchemaElement = stockModel.FindType(((IEdmSchemaElement)edmProperty.DeclaringType).FullName());
                    ExceptionUtilities.CheckObjectNotNull(stockAnnotatable, "The FindType method must be successful.");
                    stockAnnotatable = ((IEdmStructuredType)stockSchemaElement).FindProperty(edmProperty.Name);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else if (edmAnnotatable is IEdmEntitySet)
            {
                var edmEntitySet = edmAnnotatable as IEdmEntitySet;
                // TODO: No backpointer to the Entity Container from EntitySet in the API. Is this OK?
                stockAnnotatable = stockModel.EntityContainer.EntitySets().Single(m => m.Name == edmEntitySet.Name);
            }
            else if (edmAnnotatable is IEdmEnumType)
            {
                var edmEnumType = edmAnnotatable as IEdmEnumType;
                stockAnnotatable = stockModel.FindType(edmEnumType.FullName());
            }
            else
            {
                throw new NotImplementedException();
            }

            return(stockAnnotatable);
        }
Beispiel #25
0
        internal void UpdateValues(QueryCollectionValue queryCollectionValue, IEnumerable <NamedValue> namedValues)
        {
            ExceptionUtilities.CheckArgumentNotNull(queryCollectionValue, "queryCollectionValue");
            ExceptionUtilities.CheckArgumentNotNull(namedValues, "namedValues");

            var primitiveElementDataType = queryCollectionValue.Type.ElementType as QueryClrPrimitiveType;

            if (primitiveElementDataType != null)
            {
                this.UpdateRootScalarBag(queryCollectionValue, namedValues, primitiveElementDataType);
            }
            else
            {
                var complexElementDataType = queryCollectionValue.Type.ElementType as QueryComplexType;
                ExceptionUtilities.CheckObjectNotNull(complexElementDataType, "Expected QueryComplex Type, actual query type {0}", queryCollectionValue.Type);

                this.UpdateRootComplexBag(queryCollectionValue, namedValues, complexElementDataType);
            }
        }
        /// <summary>
        /// Deserializes an edmx response payload into a metadata payload representation
        /// </summary>
        /// <param name="edmxElement">The root of the edmx document</param>
        /// <returns>The metadata payload representation</returns>
        private MetadataPayloadElement DeserializeMetadata(XElement edmxElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(edmxElement, "edmxElement");
            ExceptionUtilities.Assert(edmxElement.Name.LocalName == EdmxElementName, "Deserialize metadata must be called on the 'edmx' element");

            var edmxNamespace = edmxElement.Name.Namespace;

            // Find Version attribute on metadataElement
            XAttribute versionAttribute = edmxElement.Attribute("Version");

            ExceptionUtilities.CheckObjectNotNull(versionAttribute, "Could not find 'Version' attribute");
            string edmxVersion = versionAttribute.Value;

            // Find dataservice element
            XElement dataServicesElement = edmxElement.Element(edmxNamespace.GetName("DataServices"));

            ExceptionUtilities.CheckObjectNotNull(dataServicesElement, "Could not find 'DataServices' element");

            MetadataPayloadElement metadataPayload = new MetadataPayloadElement()
            {
                EdmxVersion = edmxVersion,
            };

            AddXmlBaseAnnotation(metadataPayload, edmxElement);

            XElement[] schemaElements = dataServicesElement.Elements().Where(e => e.Name.LocalName == "Schema").ToArray();

            ExceptionUtilities.CheckObjectNotNull(this.CsdlParser, "Cannot deserialize metadata without a CSDL parser.");
            var model = this.CsdlParser.Parse(schemaElements);

            metadataPayload.EntityModelSchema = model;
            foreach (XElement schemaElement in schemaElements)
            {
                string edmNamespace    = schemaElement.Name.NamespaceName;
                string schemaNamespace = schemaElement.Attributes().Where(a => a.Name.LocalName == "Namespace").Single().Value;
                model.Annotations.Add(new SchemaNamespaceAnnotation()
                {
                    EdmNamespaceVersion = edmNamespace, SchemaNamespace = schemaNamespace
                });
            }

            return(metadataPayload);
        }
        /// <summary>
        /// Transforms the original payload by changing xml namespace prefixes.
        /// </summary>
        /// <param name="originalPayload">Original payload.</param>
        /// <param name="transformedPayload">Transformed payload.</param>
        /// <returns>True if the payload is transformed else returns false.</returns>
        public bool TryTransform(XElement originalPayload, out XElement transformedPayload)
        {
            ExceptionUtilities.CheckObjectNotNull(originalPayload, "Payload cannot be null.");

            transformedPayload = new XElement(originalPayload);

            IEnumerable <XNode> nodes             = transformedPayload.DescendantNodesAndSelf();
            List <XAttribute>   newAttributes     = new List <XAttribute>();
            XAttribute          modifiedAttribute = null;
            XElement            childNode;

            foreach (XNode node in nodes)
            {
                childNode = node as XElement;
                if (childNode != null)
                {
                    newAttributes = new List <XAttribute>();

                    foreach (XAttribute attribute in childNode.Attributes())
                    {
                        if (attribute.IsNamespaceDeclaration && !string.IsNullOrEmpty(attribute.Value) && attribute.Value != transformedPayload.GetDefaultNamespace().NamespaceName)
                        {
                            modifiedAttribute = new XAttribute(this.ChangeNamespacePrefix(attribute.Name), attribute.Value);
                            newAttributes.Add(modifiedAttribute);
                        }
                        else
                        {
                            newAttributes.Add(attribute);
                        }
                    }

                    childNode.ReplaceAttributes(newAttributes);
                }
            }

            if (modifiedAttribute != null)
            {
                return(true);
            }

            transformedPayload = null;
            return(false);
        }
Beispiel #28
0
        /// <summary>
        /// Imports association data row from an object.
        /// </summary>
        /// <param name="item">The item structurally representing association data row. Usually anonymous object.</param>
        /// <example>new { Product = 1; Category = 5 }</example>
        internal void ImportFrom(object item)
        {
            ExceptionUtilities.CheckObjectNotNull(item, "Cannot import row from null object.");

            foreach (PropertyInfo propertyInfo in item.GetType().GetProperties())
            {
                string roleName = propertyInfo.Name;
                object value    = propertyInfo.GetValue(item, null);
                var    key      = value as EntityDataKey;
                if (key != null)
                {
                    this.SetRoleKey(roleName, key);
                }
                else
                {
                    this.ImportRoleKey(roleName, value);
                }
            }
        }
Beispiel #29
0
        private void VerifyTypeNameForInsert(ODataRequest request, ODataResponse response, QueryStructuralValue inserted)
        {
            var entityInstance = request.Body.RootElement as EntityInstance;

            ExceptionUtilities.CheckObjectNotNull(entityInstance, "Cannot get expected type name because request payload was not an entity instance. It was: '{0}'", request.Body.RootElement.ElementType);

            string expectedTypeName = request.Uri.Segments.OfType <EntityTypeSegment>().Select(t => t.EntityType.FullName).LastOrDefault();

            if (entityInstance.FullTypeName != null)
            {
                expectedTypeName = entityInstance.FullTypeName;
            }

            var entityType = inserted.Type as QueryEntityType;

            ExceptionUtilities.CheckObjectNotNull(entityType, "Cannot verify type because inserted value is not an entity type. Type was: '{0}'.", inserted.Type);

            this.AssertAreEqual(expectedTypeName, entityType.EntityType.FullName, "Inserted instance type did not match", request, response);
        }
Beispiel #30
0
        /// <summary>
        /// Removes the given value from the collection
        /// </summary>
        /// <param name="targetResource">target object which defines the property</param>
        /// <param name="propertyName">name of the property whose value needs to be updated</param>
        /// <param name="resourceToBeRemoved">value of the property which needs to be removed</param>
        public virtual void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            ExceptionUtilities.CheckArgumentNotNull(resourceToBeRemoved, "resourceToBeRemoved");

            UpdatableToken.AssertIsToken(targetResource, "targetResource");
            resourceToBeRemoved = UpdatableToken.AssertIsTokenAndResolve(resourceToBeRemoved, "resourceToBeRemoved");

            // We will use the GetValue we already implement to get the IList
            IList list = this.GetValue(targetResource, propertyName) as IList;

            ExceptionUtilities.CheckObjectNotNull(list, "Property '{0}' on type '{1}' was not a list", propertyName, targetResource.GetType().Name);

            this.pendingChanges.Add(() =>
            {
                list.Remove(resourceToBeRemoved);
            });
        }