/// <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); } } } }
/// <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); } }
/// <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)); }
/// <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 + "'."); }
/// <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))); }
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"); } } }
/// <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); }
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.")); } }
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++; } } } }
/// <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)); }
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; } }
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); }
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); }
/// <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); }
/// <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); }
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); }
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); }
/// <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); } } }
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); }
/// <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); }); }