/// <summary> /// Visits a ComplexInstanceCollection, if this is not the result of a service operation call, it will be a V3 payload /// </summary> /// <param name="payloadElement">payload Element</param> public override void Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); this.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4); base.Visit(payloadElement); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); ExceptionUtilities.Assert(this.payloadVersion < DataServiceProtocolVersion.V4, "Code should not be called for V3 or greater version"); this.ExpectErrorForCollection(); base.Visit(payloadElement); }
/// <summary> /// Visits a property item. /// </summary> /// <param name="property">The property to visit.</param> protected override ODataPayloadElement VisitProperty(ODataProperty property) { ExceptionUtilities.CheckArgumentNotNull(property, "property"); object value = property.Value; if (value == null) { return(new PrimitiveProperty() { Name = property.Name, Value = new PrimitiveValue(null, null) }); } else { ODataComplexValue complexValue = value as ODataComplexValue; if (complexValue != null) { return(new ComplexProperty(property.Name, (ComplexInstance)this.Visit(complexValue))); } else { ODataCollectionValue collectionValue = value as ODataCollectionValue; if (collectionValue != null) { ODataPayloadElementCollection collection = (ODataPayloadElementCollection)this.Visit(collectionValue); ComplexMultiValue complexCollection = collection as ComplexMultiValue; if (complexCollection != null) { return(new ComplexMultiValueProperty(property.Name, complexCollection)); } else { return(new PrimitiveMultiValueProperty(property.Name, (PrimitiveMultiValue)collection)); } } else { ODataStreamReferenceValue streamReferenceValue = value as ODataStreamReferenceValue; if (streamReferenceValue != null) { NamedStreamInstance namedStream = (NamedStreamInstance)this.Visit(streamReferenceValue); namedStream.Name = property.Name; return(namedStream); } else { return(new PrimitiveProperty() { Name = property.Name, Value = (PrimitiveValue)this.Visit(value) }); } } } } }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(ComplexMultiValue payloadElement) { EntityModelTypeAnnotation typeAnnotation = payloadElement.GetAnnotation<EntityModelTypeAnnotation>(); if (payloadElement.FullTypeName == null && typeAnnotation != null) { payloadElement.FullTypeName = EntityModelUtils.GetCollectionTypeName(((IEdmCollectionTypeReference)typeAnnotation.EdmModelType).ElementType().FullName()); } base.Visit(payloadElement); }
/// <summary> /// Visits a payload element whose root is a ComplexMultiValue. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public void Visit(ComplexMultiValue payloadElement) { this.writer.StartArrayScope(); foreach (var item in payloadElement) { this.Recurse(item); } this.writer.EndScope(); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var annotation = payloadElement.Annotations.Where(a => a is DataTypeAnnotation).SingleOrDefault(); payloadElement.Annotations.Remove(annotation); this.VisitCollection(payloadElement); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(ComplexMultiValue payloadElement) { EntityModelTypeAnnotation typeAnnotation = payloadElement.GetAnnotation <EntityModelTypeAnnotation>(); if (payloadElement.FullTypeName == null && typeAnnotation != null) { payloadElement.FullTypeName = EntityModelUtils.GetCollectionTypeName(((IEdmCollectionTypeReference)typeAnnotation.EdmModelType).ElementType().FullName()); } base.Visit(payloadElement); }
/// <summary> /// Visits the children of the given payload element and replaces it with a copy if any child changes /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public virtual ODataPayloadElement Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var replaced = this.VisitCollection(payloadElement); if (!this.ShouldReplace(replaced, payloadElement)) { return(payloadElement); } return(payloadElement.ReplaceWith(new ComplexMultiValue(payloadElement.FullTypeName, payloadElement.IsNull, replaced.ToArray()))); }
/// <summary> /// Visits a payload element whose root is a ComplexMultiValue. /// </summary> /// <param name="expected">The root node of payload element being visited.</param> public void Visit(ComplexMultiValue expected) { ExceptionUtilities.CheckArgumentNotNull(expected, "expected"); var observed = this.GetNextObservedElement <ComplexMultiValue>(); using (this.Assert.WithMessage("Complex multi-value did not match expectation")) { this.Assert.AreEqual(expected.IsNull, observed.IsNull, "Null flag did not match expectation"); this.Assert.AreEqual(expected.FullTypeName, observed.FullTypeName, "Full type name did not match expectation"); this.CompareCollection(expected, observed); } }
/// <summary> /// Converts the ComplexMultiValue into an EntitySetInstance based on if the base returns a set of EntityInstances /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var replaced = (ComplexMultiValue)base.Visit(payloadElement); ExceptionUtilities.CheckObjectNotNull(replaced, "ComplexMultiValue Expected"); if (replaced.All(e => e.ElementType == ODataPayloadElementType.EntityInstance) && replaced.Count > 0) { var entitySet = new EntitySetInstance(replaced.Cast<EntityInstance>().ToArray()); return replaced.ReplaceWith(entitySet); } return replaced; }
private static ComplexMultiValue GenerateSimilarComplexMultiValue(IRandomNumberGenerator random, ComplexMultiValue currentInstance) { ComplexMultiValue instance = ((ComplexMultiValue)currentInstance.DeepCopy()); if (instance.Count != 0) { ComplexInstance val = instance.First(); int numItems = random.NextFromRange(1, 3); var newItems = Enumerable.Range(0, numItems).Select(x => GenerateSimilarComplexInstance(random, val)); instance = new ComplexMultiValue(val.FullTypeName, false, newItems.ToArray()); } return(instance); }
/// <summary> /// Converts the ComplexMultiValue into an EntitySetInstance based on if the base returns a set of EntityInstances /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var replaced = (ComplexMultiValue)base.Visit(payloadElement); ExceptionUtilities.CheckObjectNotNull(replaced, "ComplexMultiValue Expected"); if (replaced.All(e => e.ElementType == ODataPayloadElementType.EntityInstance) && replaced.Count > 0) { var entitySet = new EntitySetInstance(replaced.Cast <EntityInstance>().ToArray()); return(replaced.ReplaceWith(entitySet)); } return(replaced); }
/// <summary> /// Replaces the empty collection property with a more specific type /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(EmptyCollectionProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var memberPropertyAnnotation = payloadElement.Annotations.OfType <MemberPropertyAnnotation>().SingleOrDefault(); if (memberPropertyAnnotation != null) { var memberProperty = memberPropertyAnnotation.Property; ExceptionUtilities.CheckObjectNotNull(memberProperty, "Member property annotation was null"); var collectionType = memberProperty.PropertyType as CollectionDataType; ExceptionUtilities.CheckObjectNotNull(collectionType, "Property was not a collection type"); var primitiveType = collectionType.ElementDataType as PrimitiveDataType; if (primitiveType != null) { var primitiveCollection = new PrimitiveMultiValue(payloadElement.Value.FullTypeName, payloadElement.Value.IsNull); return(payloadElement.ReplaceWith(new PrimitiveMultiValueProperty(payloadElement.Name, primitiveCollection))); } var complexType = collectionType.ElementDataType as ComplexDataType; ExceptionUtilities.CheckObjectNotNull(complexType, "Collection element type was neither primitive nor complex: '{0}'", collectionType.ElementDataType); var complexCollection = new ComplexMultiValue(payloadElement.Value.FullTypeName, payloadElement.Value.IsNull); return(payloadElement.ReplaceWith(new ComplexMultiValueProperty(payloadElement.Name, complexCollection))); } var navigationPropertyAnnotation = payloadElement.Annotations.OfType <NavigationPropertyAnnotation>().SingleOrDefault(); if (navigationPropertyAnnotation == null) { return(payloadElement); } var entitySet = payloadElement.Value.ReplaceWith(new EntitySetInstance()); return(payloadElement.ReplaceWith(new NavigationPropertyInstance(payloadElement.Name, entitySet))); }
/// <summary> /// Converts the given payload into a series of named value pairs /// </summary> /// <param name="element">The payload to convert</param> /// <param name="queryTypeToBuild">Query Type to build</param> /// <returns>The queryValue that represents the ODataPayload</returns> public QueryValue Convert(ODataPayloadElement element, QueryType queryTypeToBuild) { var typedValue = element as ITypedValue; if (typedValue != null && typedValue.IsNull) { return(queryTypeToBuild.NullValue); } var queryCollectionType = queryTypeToBuild as QueryCollectionType; // return empty QueryCollectionValue for all types of empty collections PrimitiveCollection primitiveCollection = element as PrimitiveCollection; ComplexInstanceCollection complexInstanceCollection = element as ComplexInstanceCollection; PrimitiveMultiValue primitiveMultiValue = element as PrimitiveMultiValue; ComplexMultiValue complexMultiValue = element as ComplexMultiValue; if ((primitiveCollection != null && primitiveCollection.Count == 0) || (complexInstanceCollection != null && complexInstanceCollection.Count == 0) || (primitiveMultiValue != null && primitiveMultiValue.Count == 0) || (complexMultiValue != null && complexMultiValue.Count == 0)) { return(queryCollectionType.CreateCollectionWithValues(new QueryValue[] { })); } if (element.ElementType == ODataPayloadElementType.PrimitiveValue) { return(CreateQueryScalarValue(element, queryTypeToBuild)); } else if (queryCollectionType != null && element.ElementType == ODataPayloadElementType.PrimitiveMultiValue) { return(queryCollectionType.CreateCollectionWithValues(primitiveMultiValue.Select(p => CreateQueryScalarValue(p, queryCollectionType.ElementType)))); } var namedValues = this.PayloadElementToNamedValuesConverter.ConvertToNamedValues(element); return(this.NamedValueToQueryValueConverter.Convert(namedValues, queryTypeToBuild)); }
/// <summary> /// Visits a payload element whose root is a ComplexMultiValue. /// </summary> /// <param name="payloadElement">The root node of the payload element being visited.</param> public override void Visit(ComplexMultiValue payloadElement) { base.Visit(payloadElement); AddSerializationTypeAnnotationIfNone(payloadElement); }
private bool TryGetCollectionType(JsonObject jsonObject, out ODataPayloadElement elem) { string typeName = this.GetMetadataPropertyValue(jsonObject, TypeFieldName); elem = null; // if this object has a property with.Name "results" and it is of type "JsonArray" // Example: // "results": [ // { ... }, // { ... } // ] // if it is EntitySet or ComplexCollection // EntitySets have "_Count" and "_Next". So process it before retrning. if (jsonObject.Properties.Any(prop => prop.Name == ResultsFieldName) && jsonObject.Properties.Where(prop => prop.Name == ResultsFieldName).Single().Value.JsonType == JsonValueType.JsonArray) { string nextLink = this.GetNextLink(jsonObject); string countField = this.GetInlineCount(jsonObject); ODataPayloadElementCollection coll = this.ConvertArray((JsonArray)jsonObject.Properties.Where(p => p.Name == ResultsFieldName).Single().Value, true); if (coll.ElementType == ODataPayloadElementType.EntitySetInstance) { EntitySetInstance entitySet = coll as EntitySetInstance; entitySet.NextLink = nextLink; if (countField == null) { entitySet.InlineCount = null; } else { entitySet.InlineCount = Convert.ToInt64(countField, CultureInfo.InvariantCulture); } elem = coll; } else if (coll.ElementType == ODataPayloadElementType.LinkCollection) { LinkCollection linkCollection = (LinkCollection)coll; linkCollection.InlineCount = Convert.ToInt64(countField, CultureInfo.InvariantCulture); linkCollection.NextLink = nextLink; elem = coll; } else if (coll.ElementType == ODataPayloadElementType.PrimitiveCollection) { if (typeName != null) { PrimitiveMultiValue primitiveMultiValue = new PrimitiveMultiValue(typeName, false, ((PrimitiveCollection)coll).ToArray()); elem = primitiveMultiValue; } else { elem = coll; } } else if (coll.ElementType == ODataPayloadElementType.ComplexInstanceCollection) { if (typeName != null) { ComplexMultiValue complexMultiValue = new ComplexMultiValue(typeName, false, ((ComplexInstanceCollection)coll).ToArray()); elem = complexMultiValue; } else { elem = coll; } } else { ExceptionUtilities.Assert(coll.ElementType == ODataPayloadElementType.EmptyUntypedCollection, "Collection type unhandled: {0}", coll.ElementType); string elementTypeName; if (ODataUtilities.TryGetMultiValueElementTypeName(typeName, out elementTypeName)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); if (this.PrimitiveDataTypeConverter.ToClrType(elementTypeName) != null) { elem = new PrimitiveMultiValue(typeName, false); } else { elem = new ComplexMultiValue(typeName, false); } } else { EmptyUntypedCollection emptyCollection = (EmptyUntypedCollection)coll; if (countField != null) { emptyCollection.InlineCount = long.Parse(countField, CultureInfo.InvariantCulture); } if (nextLink != null) { emptyCollection.NextLink = nextLink; } elem = emptyCollection; } } return(true); } return(false); }
/// <summary> /// Converts the given name/value pair into a property element. /// And infers the type of property from the converted value. /// </summary> /// <param name="jsonProperty">the property value</param> /// <returns>the converted property</returns> private PropertyInstance ConvertProperty(JsonProperty jsonProperty) { if (jsonProperty.Value.JsonType == JsonValueType.JsonPrimitiveValue && ((JsonPrimitiveValue)jsonProperty.Value).Value == null) { return(new NullPropertyInstance() { Name = jsonProperty.Name }); } else { ODataPayloadElement elem = this.ConvertValue(jsonProperty.Value); ExceptionUtilities.CheckObjectNotNull(elem, "Converted property value was null"); if (elem.ElementType == ODataPayloadElementType.PrimitiveValue) { return(new PrimitiveProperty(jsonProperty.Name, (PrimitiveValue)elem)); } else if (elem.ElementType == ODataPayloadElementType.ComplexInstance) { return(new ComplexProperty(jsonProperty.Name, (ComplexInstance)elem)); } else if (elem.ElementType == ODataPayloadElementType.EntityInstance) { return(new NavigationPropertyInstance(jsonProperty.Name, new ExpandedLink(elem))); } else if (elem.ElementType == ODataPayloadElementType.DeferredLink) { DeferredLink deferredLink = (DeferredLink)elem; return(new NavigationPropertyInstance(jsonProperty.Name, deferredLink)); } else if (elem.ElementType == ODataPayloadElementType.EntitySetInstance) { return(new NavigationPropertyInstance(jsonProperty.Name, elem)); } else if (elem.ElementType == ODataPayloadElementType.ComplexMultiValue) { ComplexMultiValue complexMultiValue = (ComplexMultiValue)elem; return(new ComplexMultiValueProperty(jsonProperty.Name, complexMultiValue)); } else if (elem.ElementType == ODataPayloadElementType.PrimitiveMultiValue) { PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)elem; return(new PrimitiveMultiValueProperty(jsonProperty.Name, primitiveMultiValue)); } else if (elem.ElementType == ODataPayloadElementType.ComplexInstanceCollection) { ComplexInstanceCollection complexCollection = (ComplexInstanceCollection)elem; return(new ComplexMultiValueProperty(jsonProperty.Name, new ComplexMultiValue(null, false, complexCollection.ToArray()))); } else if (elem.ElementType == ODataPayloadElementType.PrimitiveCollection) { PrimitiveCollection primitiveCollection = (PrimitiveCollection)elem; return(new PrimitiveMultiValueProperty(jsonProperty.Name, new PrimitiveMultiValue(null, false, primitiveCollection.ToArray()))); } else if (elem.ElementType == ODataPayloadElementType.NamedStreamInstance) { NamedStreamInstance nsi = (NamedStreamInstance)elem; nsi.Name = jsonProperty.Name; return(nsi); } else { ExceptionUtilities.Assert(elem.ElementType == ODataPayloadElementType.EmptyUntypedCollection, "Do not know how to handle element of type" + elem.ElementType); return(new EmptyCollectionProperty(jsonProperty.Name, (EmptyUntypedCollection)elem)); } } }
/// <summary> /// Visits a payload element whose root is a ComplexMultiValue. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public void Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var current = this.expectedValueStack.Peek(); var value = current as QueryCollectionValue; ExceptionUtilities.CheckObjectNotNull(value, "Value was not a collection. Value was: '{0}'", current.ToString()); this.VerifyTypeName(value, payloadElement.FullTypeName, "Type name did not match expectation for complex multi-value"); this.parent.Assert.AreEqual(value.Elements.Count, payloadElement.Count, "Complex multi-value count did not match expectation"); for (int i = 0; i < value.Elements.Count; i++) { this.RecurseWithMessage(payloadElement[i], value.Elements[i], "Complex instance at position {0} did not match expectation", i + 1); } }
/// <summary> /// Builds a complex instance from the given payloadElements to represent a parameters payload. /// </summary> /// <param name="payloadElements">Each ODataPayloadElement represents the value for each parameter.</param> /// <param name="model">EdmModel instance.</param> /// <param name="functionImportName">Name of the function import to add to the model.</param> /// <returns></returns> private static ComplexInstance PayloadElementsToParameterPayload(ODataPayloadElement[] payloadElements, EdmModel model, string functionImportName) { EdmOperationImport operationImport = (EdmOperationImport)model.EntityContainer.FindOperationImports(functionImportName).FirstOrDefault(); EdmOperation operation = (EdmOperation)operationImport.Operation; var parameterPayload = new ComplexInstance(null, false); for (int idx = 0; idx < payloadElements.Length; idx++) { ODataPayloadElement p = payloadElements[idx]; string parameterName = "p" + idx; PropertyInstance parameter; IEdmTypeReference entityModelType = p.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType; switch (p.ElementType) { case ODataPayloadElementType.PrimitiveValue: object clrValue = ((PrimitiveValue)p).ClrValue; PrimitiveValue primitiveValue = new PrimitiveValue(clrValue == null ? null : clrValue.GetType().FullName, clrValue); primitiveValue.CopyAnnotation <PrimitiveValue, EntityModelTypeAnnotation>(p); parameter = new PrimitiveProperty(parameterName, primitiveValue); operation.AddParameter(parameterName, MetadataUtils.GetPrimitiveTypeReference(primitiveValue.ClrValue.GetType())); break; case ODataPayloadElementType.ComplexInstance: parameter = new ComplexProperty(parameterName, (ComplexInstance)p); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.PrimitiveMultiValue: PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)p; if (primitiveMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null) { primitiveMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false)); } parameter = new PrimitiveMultiValueProperty(parameterName, primitiveMultiValue); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.ComplexMultiValue: ComplexMultiValue complexMultiValue = (ComplexMultiValue)p; if (complexMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null) { complexMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false)); } parameter = new ComplexMultiValueProperty(parameterName, complexMultiValue); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.EntityInstance: parameter = new NavigationPropertyInstance(parameterName, (EntityInstance)p); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.EntitySetInstance: parameter = new NavigationPropertyInstance(parameterName, (EntitySetInstance)p); operation.AddParameter(parameterName, entityModelType); break; default: throw new NotSupportedException("PayloadElementsToParameterPayload() is called on unsupported ODataPayloadElement type: " + p.ElementType); } parameterPayload.Add(parameter); } parameterPayload.ExpectedFunctionImport(operationImport); return(parameterPayload); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public virtual void Visit(ComplexMultiValue payloadElement) { this.VisitCollection(payloadElement); }
public override void Visit(ComplexMultiValue payloadElement) { base.Visit(payloadElement); this.AddTypeAnnotation(payloadElement, payloadElement.FullTypeName); }
/// <summary> /// Visits a collection of parameters. /// </summary> /// <param name="parameters">The parameters to visit.</param> protected override ODataPayloadElement VisitParameters(ODataParameters parameters) { ExceptionUtilities.CheckArgumentNotNull(parameters, "parameters"); ComplexInstance result = new ComplexInstance(); result.IsNull = parameters.Count == 0; foreach (var parameter in parameters) { if (parameter.Value == null) { result.Add(new PrimitiveProperty(parameter.Key, null, null)); continue; } ODataComplexValue odataComplexValue = parameter.Value as ODataComplexValue; ODataCollectionStart odataCollectionStart = parameter.Value as ODataCollectionStart; if (odataCollectionStart != null) { ODataCollectionItemsObjectModelAnnotation annotation = odataCollectionStart.GetAnnotation <ODataCollectionItemsObjectModelAnnotation>(); if (annotation.OfType <ODataComplexValue>().FirstOrDefault() != null) { ComplexMultiValue complexCollection = PayloadBuilder.ComplexMultiValue(); foreach (var value in annotation) { complexCollection.Item(this.VisitComplexValue(value as ODataComplexValue) as ComplexInstance); } ComplexMultiValueProperty complexCollectionProperty = new ComplexMultiValueProperty(parameter.Key, complexCollection); result.Add(complexCollectionProperty); } else { PrimitiveMultiValue primitiveCollection = PayloadBuilder.PrimitiveMultiValue(); foreach (var value in annotation) { primitiveCollection.Item(value); } PrimitiveMultiValueProperty primitiveCollectionProperty = new PrimitiveMultiValueProperty(parameter.Key, primitiveCollection); result.Add(primitiveCollectionProperty); } } else if (odataComplexValue != null) { ComplexInstance complexInstance = PayloadBuilder.ComplexValue(odataComplexValue.TypeName); complexInstance.IsNull = false; foreach (ODataProperty odataProperty in odataComplexValue.Properties) { complexInstance.Property(odataProperty.Name, this.Visit(odataProperty.Value)); } result.Add(new ComplexProperty(parameter.Key, complexInstance)); } else { result.Add(new PrimitiveProperty(parameter.Key, null, PayloadBuilder.PrimitiveValue(parameter.Value).ClrValue)); } } return(result); }
/// <summary> /// Visits a collection item. /// </summary> /// <param name="collectionValue">The collection to visit.</param> protected override ODataPayloadElement VisitCollectionValue(ODataCollectionValue collectionValue) { if (collectionValue == null) { return(new PrimitiveMultiValue(null, true)); } bool?isPrimitiveCollection = null; // Try to parse the type name and if the item type name is a primitive EDM type, then this is a primitive collection. string typeName = collectionValue.TypeName; if (typeName != null) { string itemTypeName = EntityModelUtils.GetCollectionItemTypeName(typeName); isPrimitiveCollection = itemTypeName != null && EntityModelUtils.GetPrimitiveEdmType(itemTypeName) != null; } List <object> items = new List <object>(); foreach (object item in collectionValue.Items) { if (!isPrimitiveCollection.HasValue) { ODataComplexValue complexItemValue = item as ODataComplexValue; // If the first item is a complex value, then the collection is of complex kind. // Note that if the first item is null, we assume primitive collection, since we can't really decide (and it's an invalid thing anyway) isPrimitiveCollection = complexItemValue == null; } if (isPrimitiveCollection.Value) { items.Add((PrimitiveValue)this.Visit(item)); } else { ODataComplexValue complexItemValue = item as ODataComplexValue; ExceptionUtilities.Assert( item == null || complexItemValue != null, "The collection was determined to be of complex values but one of its items is not an ODataComplexValue."); items.Add((ComplexInstance)this.Visit(complexItemValue)); } } if (!isPrimitiveCollection.HasValue) { // If we could not tell until now (possible only if there was no type name and no items) // assume primitive collection. isPrimitiveCollection = true; } if (isPrimitiveCollection == true) { PrimitiveMultiValue primitiveCollection = new PrimitiveMultiValue(typeName, false); foreach (object item in items) { primitiveCollection.Add((PrimitiveValue)item); } this.ConvertSerializationTypeNameAnnotation(collectionValue, primitiveCollection); return(primitiveCollection); } else { ComplexMultiValue complexCollection = new ComplexMultiValue(typeName, false); foreach (object item in items) { complexCollection.Add((ComplexInstance)item); } this.ConvertSerializationTypeNameAnnotation(collectionValue, complexCollection); return(complexCollection); } }
private static ComplexMultiValue GenerateSimilarComplexMultiValue(IRandomNumberGenerator random, ComplexMultiValue currentInstance) { ComplexMultiValue instance = ((ComplexMultiValue)currentInstance.DeepCopy()); if (instance.Count != 0) { ComplexInstance val = instance.First(); int numItems = random.NextFromRange(1, 3); var newItems = Enumerable.Range(0, numItems).Select(x => GenerateSimilarComplexInstance(random, val)); instance = new ComplexMultiValue(val.FullTypeName, false, newItems.ToArray()); } return instance; }
/// <summary> /// Replaces the empty collection property with a more specific type /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(EmptyCollectionProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var memberPropertyAnnotation = payloadElement.Annotations.OfType<MemberPropertyAnnotation>().SingleOrDefault(); if (memberPropertyAnnotation != null) { var memberProperty = memberPropertyAnnotation.Property; ExceptionUtilities.CheckObjectNotNull(memberProperty, "Member property annotation was null"); var collectionType = memberProperty.PropertyType as CollectionDataType; ExceptionUtilities.CheckObjectNotNull(collectionType, "Property was not a collection type"); var primitiveType = collectionType.ElementDataType as PrimitiveDataType; if (primitiveType != null) { var primitiveCollection = new PrimitiveMultiValue(payloadElement.Value.FullTypeName, payloadElement.Value.IsNull); return payloadElement.ReplaceWith(new PrimitiveMultiValueProperty(payloadElement.Name, primitiveCollection)); } var complexType = collectionType.ElementDataType as ComplexDataType; ExceptionUtilities.CheckObjectNotNull(complexType, "Collection element type was neither primitive nor complex: '{0}'", collectionType.ElementDataType); var complexCollection = new ComplexMultiValue(payloadElement.Value.FullTypeName, payloadElement.Value.IsNull); return payloadElement.ReplaceWith(new ComplexMultiValueProperty(payloadElement.Name, complexCollection)); } var navigationPropertyAnnotation = payloadElement.Annotations.OfType<NavigationPropertyAnnotation>().SingleOrDefault(); if (navigationPropertyAnnotation == null) { return payloadElement; } var entitySet = payloadElement.Value.ReplaceWith(new EntitySetInstance()); return payloadElement.ReplaceWith(new NavigationPropertyInstance(payloadElement.Name, entitySet)); }
/// <summary> /// Gets the data type of a property value specified in the property instance payload element. /// </summary> /// <param name="propertyInstance">The property instance payload element to inspect.</param> /// <returns>The data type of the property value (can be used to define the metadata for this property).</returns> public static IEdmTypeReference GetPayloadEdmElementPropertyValueType(PropertyInstance propertyInstance) { ExceptionUtilities.CheckArgumentNotNull(propertyInstance, "propertyInstance"); IEdmTypeReference result = GetEdmTypeFromEntityModelTypeAnnotation(propertyInstance); if (result == null) { switch (propertyInstance.ElementType) { case ODataPayloadElementType.NullPropertyInstance: NullPropertyInstance nullPropertyInstance = (NullPropertyInstance)propertyInstance; if (nullPropertyInstance.FullTypeName != null) { result = GetPrimitiveEdmType(nullPropertyInstance.FullTypeName); if (result == null) { result = CreateComplexTypeReference(nullPropertyInstance.FullTypeName); } } break; case ODataPayloadElementType.PrimitiveProperty: result = GetEdmTypeFromEntityModelTypeAnnotation(((PrimitiveProperty)propertyInstance).Value); if (result == null) { result = GetPrimitiveEdmType(((PrimitiveProperty)propertyInstance).Value.FullTypeName); } break; case ODataPayloadElementType.ComplexProperty: result = GetEdmTypeFromEntityModelTypeAnnotation(((ComplexProperty)propertyInstance).Value); if (result == null) { result = CreateComplexTypeReference(((ComplexProperty)propertyInstance).Value.FullTypeName); } break; case ODataPayloadElementType.NamedStreamInstance: result = EdmCoreModel.Instance.GetStream(isNullable: false); break; case ODataPayloadElementType.PrimitiveMultiValueProperty: PrimitiveMultiValue primitiveMultiValue = ((PrimitiveMultiValueProperty)propertyInstance).Value; result = GetEdmTypeFromEntityModelTypeAnnotation(primitiveMultiValue); if (result == null && primitiveMultiValue.FullTypeName != null) { string itemTypeName = EntityModelUtils.GetCollectionItemTypeName(primitiveMultiValue.FullTypeName); if (itemTypeName != null) { result = EdmCoreModel.GetCollection(GetPrimitiveEdmType(itemTypeName)); } } break; case ODataPayloadElementType.ComplexMultiValueProperty: ComplexMultiValue complexMultiValue = ((ComplexMultiValueProperty)propertyInstance).Value; result = GetEdmTypeFromEntityModelTypeAnnotation(complexMultiValue); if (result == null && complexMultiValue.FullTypeName != null) { string itemTypeName = EntityModelUtils.GetCollectionItemTypeName(complexMultiValue.FullTypeName); if (itemTypeName != null) { return(EdmCoreModel.GetCollection(CreateComplexTypeReference(itemTypeName))); } } break; case ODataPayloadElementType.PrimitiveCollection: case ODataPayloadElementType.ComplexInstanceCollection: ExceptionUtilities.Assert(false, "Primitive and complex collections cannot be used in properties but only at the top-level."); return(null); default: ExceptionUtilities.Assert(false, "GetPayloadElementPropertyValueType doesn't support '{0}' yet.", propertyInstance.ElementType); return(null); } } // Use the expected type if there's any since it also specifies metadata if (result == null) { ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation = propertyInstance.GetAnnotation <ExpectedTypeODataPayloadElementAnnotation>(); if (expectedTypeAnnotation != null && expectedTypeAnnotation.ExpectedType != null) { result = expectedTypeAnnotation.EdmExpectedType; } } return(result); }
/// <summary> /// Visits the payload element. /// </summary> /// <param name="payloadElement">The payload element to visit.</param> public override void Visit(ComplexMultiValue payloadElement) { var observed = this.GetNextObservedElement <ComplexMultiValue>(); this.VisitEnumerable(payloadElement, observed); }