private static ResourceType CreateResourceType(Type type, ResourceTypeKind kind, ResourceType baseType, IDictionary <Type, ResourceType> knownTypes, IDictionary <ResourceType, List <ResourceType> > childTypes) { ResourceType type2 = new ResourceType(type, kind, baseType, type.Namespace, CommonUtil.GetModelTypeName(type), type.IsAbstract) { IsOpenType = false }; if (type.GetCustomAttributes(typeof(HasStreamAttribute), true).Length == 1) { type2.IsMediaLinkEntry = true; } foreach (object obj2 in type.GetCustomAttributes(typeof(NamedStreamAttribute), baseType == null)) { type2.AddProperty(new ResourceProperty(((NamedStreamAttribute)obj2).Name, ResourcePropertyKind.Stream, ResourceType.PrimitiveResourceTypeMap.GetPrimitive(typeof(Stream)))); } knownTypes.Add(type, type2); childTypes.Add(type2, null); if (baseType != null) { if (childTypes[baseType] == null) { childTypes[baseType] = new List <ResourceType>(); } childTypes[baseType].Add(type2); } return(type2); }
/// <summary> /// Constructs a new instance of Astoria type using the specified clr type. /// </summary> /// <param name="instanceType">CLR type that represents the flow format inside the Astoria runtime.</param> /// <param name="resourceTypeKind">Kind of the resource type.</param> /// <param name="baseType">Base type of the resource type.</param> /// <param name="namespaceName">Namespace name of the given resource type.</param> /// <param name="name">Name of the given resource type.</param> /// <param name="isAbstract">Whether the resource type is an abstract type or not.</param> public ResourceType( Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : this(instanceType, baseType, namespaceName, name, isAbstract) { ExceptionUtils.CheckArgumentNotNull(instanceType, "instanceType"); ExceptionUtils.CheckArgumentStringNotNullOrEmpty(name, "name"); CheckResourceTypeKind(resourceTypeKind, "resourceTypeKind"); if (resourceTypeKind == ResourceTypeKind.Primitive || resourceTypeKind == ResourceTypeKind.MultiValue) { throw new ArgumentException(Strings.ResourceType_InvalidValueForResourceTypeKind, "resourceTypeKind"); } if (baseType != null && baseType.ResourceTypeKind != resourceTypeKind) { throw new ArgumentException( Strings.ResourceType_InvalidResourceTypeKindInheritance(resourceTypeKind.ToString(), baseType.ResourceTypeKind.ToString()), "resourceTypeKind"); } if (instanceType.IsValueType) { throw new ArgumentException(Strings.ResourceType_TypeCannotBeValueType, "instanceType"); } this.resourceTypeKind = resourceTypeKind; }
internal static void CheckResourceTypeKind(ResourceTypeKind kind, string parameterName) { if ((kind < ResourceTypeKind.EntityType) || (kind > ResourceTypeKind.EntityCollection)) { throw new ArgumentException(System.Data.Services.Strings.InvalidEnumValue(kind.GetType().Name), parameterName); } }
/// <summary> /// Validates a type name to ensure that it's not an empty string. /// </summary> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="typeName">The type name to validate.</param> /// <param name="typeKind">The expected type kind for the given type name.</param> /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param> /// <returns>The resource type with the given name and kind if the metadata was available, otherwise null.</returns> internal static ResourceType ValidateTypeName(DataServiceMetadataProviderWrapper metadata, string typeName, ResourceTypeKind typeKind, bool isOpenPropertyType) { DebugUtils.CheckNoExternalCallers(); if (typeName == null) { // if we have metadata the type name of an entry or a complex value of an open property must not be null if (metadata != null && (typeKind == ResourceTypeKind.EntityType || isOpenPropertyType)) { throw new ODataException(Strings.ODataWriterCore_MissingTypeNameWithMetadata); } return null; } // we do not allow empty type names if (typeName.Length == 0) { throw new ODataException(Strings.ODataWriter_TypeNameMustNotBeEmpty); } // If we do have metadata, lookup the type and translate it to ResourceType. ResourceType resourceType = null; if (metadata != null) { resourceType = typeKind == ResourceTypeKind.MultiValue ? ValidateMultiValueTypeName(metadata, typeName) : ValidateNonMultiValueTypeName(metadata, typeName, typeKind); } return resourceType; }
internal IEdmSchemaType EnsureSchemaType(ResourceType resourceType) { IEdmSchemaType type; ResourceTypeKind resourceTypeKind = resourceType.ResourceTypeKind; if (resourceTypeKind == ResourceTypeKind.Primitive) { return(MetadataProviderUtils.CreatePrimitiveTypeReference(resourceType).PrimitiveDefinition()); } string typeNamespace = this.GetTypeNamespace(resourceType); string key = ComputeSchemaTypeCacheKey(typeNamespace, resourceType); if (this.schemaTypeCache.TryGetValue(key, out type)) { return(type); } switch (resourceTypeKind) { case ResourceTypeKind.EntityType: return(this.AddEntityType(resourceType, typeNamespace)); case ResourceTypeKind.ComplexType: return(this.AddComplexType(resourceType, typeNamespace)); } throw new InvalidOperationException(System.Data.Services.Strings.MetadataProviderEdmModel_UnsupportedSchemaTypeKind(resourceTypeKind.ToString())); }
private static ReadOnlyCollection <OperationParameter> ValidateParameters(System.Data.Services.Providers.OperationParameterBindingKind operationParameterBindingKind, IEnumerable <OperationParameter> parameters) { if (parameters == null) { return(OperationParameter.EmptyOperationParameterCollection); } ReadOnlyCollection <OperationParameter> onlys = new ReadOnlyCollection <OperationParameter>(new List <OperationParameter>(parameters)); HashSet <string> set = new HashSet <string>(StringComparer.Ordinal); int num = (operationParameterBindingKind != System.Data.Services.Providers.OperationParameterBindingKind.Never) ? 0 : -1; for (int i = 0; i < onlys.Count; i++) { OperationParameter parameter = onlys[i]; if (!set.Add(parameter.Name)) { throw new ArgumentException(System.Data.Services.Strings.ServiceOperation_DuplicateParameterName(parameter.Name), "parameters"); } if (i > num) { ResourceTypeKind resourceTypeKind = parameter.ParameterType.ResourceTypeKind; switch (resourceTypeKind) { case ResourceTypeKind.EntityType: case ResourceTypeKind.EntityCollection: throw new ArgumentException(System.Data.Services.Strings.ServiceOperation_NonBindingParametersCannotBeEntityorEntityCollection(parameter.Name, resourceTypeKind)); } } } return(onlys); }
/// <summary> /// Check whether the given value for <see cref="ResourceTypeKind"/> is valid. If not, throw argument exception. /// </summary> /// <param name="kind">Value for ResourceTypeKind.</param> /// <param name="parameterName">Name of the parameter.</param> /// <exception cref="ArgumentException">If the value is not valid.</exception> private static void CheckResourceTypeKind(ResourceTypeKind kind, string parameterName) { if (kind < ResourceTypeKind.EntityType || kind > ResourceTypeKind.MultiValue) { throw new ArgumentException(Strings.General_InvalidEnumValue(kind.GetType().Name), parameterName); } }
public ResourceTypeMapping( Type clientClrType, ResourceTypeKind resourceTypeKind, ResourceTypeMapping baseType, string namespaceName, string name, bool isAbstract) : base(clientClrType, resourceTypeKind, baseType, namespaceName, name, isAbstract) { }
/// <summary> /// Initializes a new instance of the LazyResourceType class /// </summary> /// <param name="instanceType">Instance type that will back this metadata type</param> /// <param name="resourceTypeKind">The Type, complex or Resource</param> /// <param name="baseType">BaseType of the ResourceTYpe</param> /// <param name="namespaceName">Namespace of the type</param> /// <param name="name">Name of the type</param> /// <param name="isAbstract">Whether the type is abstract or not</param> public LazyResourceType( Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : base(instanceType, resourceTypeKind, baseType, namespaceName, name, isAbstract) { this.LazyProperties = new List<ResourceProperty>(); }
/// <summary> /// Initializes a new instance of the LazyResourceType class /// </summary> /// <param name="instanceType">Instance type that will back this metadata type</param> /// <param name="resourceTypeKind">The Type, complex or Resource</param> /// <param name="baseType">BaseType of the ResourceTYpe</param> /// <param name="namespaceName">Namespace of the type</param> /// <param name="name">Name of the type</param> /// <param name="isAbstract">Whether the type is abstract or not</param> public LazyResourceType( Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : base(instanceType, resourceTypeKind, baseType, namespaceName, name, isAbstract) { this.LazyProperties = new List <ResourceProperty>(); }
internal ResourceType AddResourceType(string name, ResourceTypeKind kind, string typeNamespace, ResourceType baseType, string clrType = null) { name.ThrowIfNullOrEmpty("name", Resources.NullIsPassedAsResourceName, new object[0]); if (typeNamespace == null) { typeNamespace = this.ContainerNamespace; } ResourceType resourceTypeWithDescription = new ResourceTypeWithDescription(typeof(DSResource), kind, baseType, typeNamespace, name, false); resourceTypeWithDescription.CanReflectOnInstanceType = false; resourceTypeWithDescription.CustomState = new ResourceCustomState(clrType); this.ResourceTypes.Add(resourceTypeWithDescription.FullName, resourceTypeWithDescription); return(resourceTypeWithDescription); }
/// <summary> /// Constructs a new instance of Resource type for the either given clr primitive type or multiValue type. /// This constructor must be called only for primitive or multiValue types. /// </summary> /// <param name="type">The instance type of the resource type.</param> /// <param name="resourceTypeKind">Kind of the resource type.</param> /// <param name="namespaceName">Namespace of the type.</param> /// <param name="name">Name of the type.</param> internal ResourceType(Type type, ResourceTypeKind resourceTypeKind, string namespaceName, string name) : this(type, null, namespaceName, name, false) { DebugUtils.CheckNoExternalCallers(); #if DEBUG Debug.Assert( resourceTypeKind == ResourceTypeKind.Primitive || resourceTypeKind == ResourceTypeKind.MultiValue, "Only primitive or multiValue resource types can be created by this constructor."); Debug.Assert( resourceTypeKind != ResourceTypeKind.Primitive || PrimitiveTypeUtils.IsPrimitiveType(type), "Primitive resource types must have a primitive instance type."); #endif this.resourceTypeKind = resourceTypeKind; this.isReadOnly = true; }
private ResourceType CreateResourceType(Type type, ResourceTypeKind kind, ResourceType baseType) { var resourceType = new ResourceType(type, kind, baseType, type.Namespace, GetResourceTypeName(type), type.IsAbstract); resourceType.IsOpenType = false; _knownResourceTypes.Add(type, resourceType); _childResourceTypes.Add(resourceType, null); if (baseType != null) { if (_childResourceTypes[baseType] == null) { _childResourceTypes[baseType] = new List <ResourceType>(); } _childResourceTypes[baseType].Add(resourceType); } _unvisitedResourceTypes.Enqueue(resourceType); return(resourceType); }
private ResourceType GenerateComplexTypeSchema(Type clrType, ResourceTypeKind resourceTypeKind) { if (this.complexTypeResourceTypes.ContainsKey(clrType.FullName)) { return(this.complexTypeResourceTypes[clrType.FullName]); } ResourceType resourceType = new ResourceType(clrType, resourceTypeKind, null, "TenantReporting", clrType.Name, false); foreach (PropertyInfo propertyInfo in clrType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)) { Type type = propertyInfo.PropertyType; Type type2; if (ReportingSchema.IsNullableType(type, out type2)) { type = type2; } ResourcePropertyKind resourcePropertyKind = 1; ResourceType resourceType2 = ResourceType.GetPrimitiveResourceType(type); if (resourceType2 == null) { if (type.IsEnum || type.IsValueType) { throw new NotSupportedException("struct and enum are not supported. For struct, try to change it to class. For enum, try to change it to integer or string."); } if (type.Equals(clrType)) { resourceType2 = resourceType; } else { resourceType2 = this.GenerateComplexTypeSchema(type, 1); } resourcePropertyKind = 4; } resourceType.AddProperty(new ResourceProperty(propertyInfo.Name, resourcePropertyKind, resourceType2)); } if (resourceTypeKind == 1) { this.complexTypeResourceTypes.Add(clrType.FullName, resourceType); } return(resourceType); }
/// <summary> /// Validates the input parameters and convert it to a read only collection of parameters. /// </summary> /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param> /// <param name="parameters">In-order parameters for this operation.</param> /// <returns>A read only collection of parameters.</returns> private static ReadOnlyCollection <OperationParameter> ValidateParameters(OperationParameterBindingKind operationParameterBindingKind, IEnumerable <OperationParameter> parameters) { Debug.Assert( operationParameterBindingKind == OperationParameterBindingKind.Never || operationParameterBindingKind == OperationParameterBindingKind.Always || operationParameterBindingKind == OperationParameterBindingKind.Sometimes, "Unexpected value of OperationParameterBindingKind."); ReadOnlyCollection <OperationParameter> resultParameters; if (parameters == null) { resultParameters = OperationParameter.EmptyOperationParameterCollection; } else { resultParameters = new ReadOnlyCollection <OperationParameter>(new List <OperationParameter>(parameters)); HashSet <string> paramNames = new HashSet <string>(StringComparer.Ordinal); int bindingParameterIndex = operationParameterBindingKind != OperationParameterBindingKind.Never ? 0 : -1; for (int idx = 0; idx < resultParameters.Count; idx++) { OperationParameter parameter = resultParameters[idx]; if (!paramNames.Add(parameter.Name)) { throw new ArgumentException(Strings.ServiceOperation_DuplicateParameterName(parameter.Name), "parameters"); } if (idx > bindingParameterIndex) { ResourceTypeKind parameterTypeKind = parameter.ParameterType.ResourceTypeKind; if (parameterTypeKind == ResourceTypeKind.EntityType || parameterTypeKind == ResourceTypeKind.EntityCollection) { throw new ArgumentException(Strings.ServiceOperation_NonBindingParametersCannotBeEntityorEntityCollection(parameter.Name, parameterTypeKind)); } } } } return(resultParameters); }
private ResourceType BuildHierarchyForType(Type type, ResourceTypeKind kind) { var maps = new List <BsonClassMap>(); var baseClassMap = BsonClassMap.LookupClassMap(type); ResourceType entityResourceType = null; while (baseClassMap != null && !_knownResourceTypes.TryGetValue(baseClassMap.ClassType, out entityResourceType)) { maps.Add(baseClassMap); baseClassMap = baseClassMap.BaseClassMap; if (baseClassMap.ClassType == typeof(object)) { baseClassMap = null; } } if (entityResourceType != null) { if (entityResourceType.ResourceTypeKind == kind) { if (maps.Count == 0) { return(entityResourceType); } } else { return(null); } } for (int i = maps.Count - 1; i >= 0; i--) { entityResourceType = CreateResourceType(maps[i].ClassType, kind, entityResourceType); } PopulateMetadataForTypes(); return(entityResourceType); }
public static SerializerBase CreateSerializer(ResourceType resourceType) { ResourceTypeKind resourceTypeKind = resourceType.ResourceTypeKind; switch (resourceTypeKind) { case ResourceTypeKind.ComplexType: { return(new ComplexTypeSerializer(resourceType)); } case ResourceTypeKind.Primitive: { return(new PrimitiveTypeSerializer(resourceType)); } case ResourceTypeKind.Collection: { return(new CollectionResourceTypeSerializer(resourceType)); } } return(new EntityTypeSerializer(resourceType, false)); }
public ResourceType(Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) { if (instanceType == null) { throw new ArgumentNullException("instanceType"); } if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (resourceTypeKind == ResourceTypeKind.Primitive) { throw new ArgumentException("'Primitive' is not a valid value for resourceTypeKind", "resourceTypeKind"); } if (instanceType.IsValueType) { throw new ArgumentException("Clr type for the resource type cannot be a value type."); } this.InstanceType = instanceType; this.ResourceTypeKind = resourceTypeKind; this.BaseType = baseType; if (String.IsNullOrEmpty(namespaceName)) { this.FullName = name; } else { this.FullName = namespaceName + "." + name; } this.Name = name; this.nameSpace = namespaceName; this.IsAbstract = isAbstract; // Appears to always be true this.CanReflectOnInstanceType = true; }
/// <summary> /// Constructs a new instance of Astoria type using the specified clr type /// </summary> /// <param name="instanceType">clr type that represents the flow format inside the Astoria runtime</param> /// <param name="resourceTypeKind"> kind of the resource type</param> /// <param name="baseType">base type of the resource type</param> /// <param name="namespaceName">Namespace name of the given resource type.</param> /// <param name="name">name of the given resource type.</param> /// <param name="isAbstract">whether the resource type is an abstract type or not.</param> public ResourceType( Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : this(instanceType, baseType, namespaceName, name, isAbstract) { WebUtil.CheckArgumentNull(instanceType, "instanceType"); WebUtil.CheckStringArgumentNull(name, "name"); WebUtil.CheckResourceTypeKind(resourceTypeKind, "resourceTypeKind"); if (resourceTypeKind == ResourceTypeKind.Primitive) { throw new ArgumentException(Strings.ResourceType_InvalidValueForResourceTypeKind, "resourceTypeKind"); } if (instanceType.IsValueType) { throw new ArgumentException(Strings.ResourceType_TypeCannotBeValueType, "instanceType"); } this.resourceTypeKind = resourceTypeKind; }
/// <summary> /// Resolve a type name against the provided metadata. If no type name is given we either throw (if a type name on the value is required, e.g., on entries) /// or infer the type from metadata (if available). /// </summary> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="typeFromMetadata">The type inferred from metadata or null if no metadata is available.</param> /// <param name="typeName">The type name to be resolved.</param> /// <param name="typeKind">The expected type kind of the resolved type.</param> /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param> /// <returns>A resource type for the <paramref name="typeName"/> or null if no metadata is available.</returns> internal static ResourceType ResolveTypeName(DataServiceMetadataProviderWrapper metadata, ResourceType typeFromMetadata, ref string typeName, ResourceTypeKind typeKind, bool isOpenPropertyType) { DebugUtils.CheckNoExternalCallers(); ResourceType typeFromValue = ValidationUtils.ValidateTypeName(metadata, typeName, typeKind, isOpenPropertyType); typeFromValue = ValidationUtils.ValidateMetadataType(typeFromMetadata, typeFromValue, typeKind); // derive the type name from the metadata if available if (typeName == null && typeFromValue != null) { typeName = typeFromValue.FullName; } return typeFromValue; }
private ResourceType AddDocumentType(DocumentDbContext context, string collectionName, JToken document, ResourceTypeKind resourceTypeKind) { var collectionType = resourceTypeKind == ResourceTypeKind.EntityType ? this.instanceMetadataCache.AddEntityType(collectionName) : this.instanceMetadataCache.AddComplexType(collectionName); bool hasObjectId = false; if (document != null) { foreach (var element in document) { var property = element as JProperty; RegisterResourceProperty(context, collectionType, property); if (IsObjectId(property)) { hasObjectId = true; } } } if (!hasObjectId) { if (resourceTypeKind == ResourceTypeKind.EntityType) { this.instanceMetadataCache.AddKeyProperty(collectionType, MappedObjectIdName, MappedObjectIdType); } AddProviderType(collectionName, ProviderObjectIdName, new JProperty(ProviderObjectIdName, string.Empty), true); // TODO } if (resourceTypeKind == ResourceTypeKind.EntityType) { this.instanceMetadataCache.AddResourceSet(collectionName, collectionType); } return(collectionType); }
private static ResourceType CreateResourceType(Type type, ResourceTypeKind kind, ResourceType baseType, IDictionary<Type, ResourceType> knownTypes, IDictionary<ResourceType, List<ResourceType>> childTypes) { ResourceType type2 = new ResourceType(type, kind, baseType, type.Namespace, CommonUtil.GetModelTypeName(type), type.IsAbstract) { IsOpenType = false }; if (type.GetCustomAttributes(typeof(HasStreamAttribute), true).Length == 1) { type2.IsMediaLinkEntry = true; } foreach (object obj2 in type.GetCustomAttributes(typeof(NamedStreamAttribute), baseType == null)) { type2.AddProperty(new ResourceProperty(((NamedStreamAttribute) obj2).Name, ResourcePropertyKind.Stream, ResourceType.PrimitiveResourceTypeMap.GetPrimitive(typeof(Stream)))); } knownTypes.Add(type, type2); childTypes.Add(type2, null); if (baseType != null) { if (childTypes[baseType] == null) { childTypes[baseType] = new List<ResourceType>(); } childTypes[baseType].Add(type2); } return type2; }
private static string GetResourcePropertyName(JProperty element, ResourceTypeKind resourceTypeKind) { return(IsObjectId(element) && resourceTypeKind != ResourceTypeKind.ComplexType ? DocumentDbMetadata.MappedObjectIdName : NormalizeResourcePropertyName(element.Name)); }
/// <summary> /// Validates that <paramref name="typeName"/> is a valid type name of the specified kind (<paramref name="typeKind"/>). /// </summary> /// <param name="metadata">The metadata against which to validate the type name.</param> /// <param name="typeName">The type name to validate.</param> /// <param name="typeKind">The expected <see cref="ResourceTypeKind"/> of the type.</param> /// <returns>A <see cref="ResourceType"/> for the <paramref name="typeName"/>.</returns> internal static ResourceType ValidateNonMultiValueTypeName(DataServiceMetadataProviderWrapper metadata, string typeName, ResourceTypeKind typeKind) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(metadata != null, "metadata != null"); ResourceType resourceType = metadata.TryResolveResourceType(typeName); if (resourceType == null) { throw new ODataException(Strings.ODataWriterCore_UnrecognizedTypeName(typeName, typeKind)); } if (resourceType.ResourceTypeKind != typeKind) { throw new ODataException(Strings.ODataWriterCore_IncorrectTypeKind(typeName, typeKind.ToString(), resourceType.ResourceTypeKind.ToString())); } return(resourceType); }
/// <summary> /// Validates that the (optional) <paramref name="typeFromMetadata"/> is compatible with the (optional) <paramref name="typeFromValue"/>. /// </summary> /// <param name="typeFromMetadata">The (optional) type from the metadata definition.</param> /// <param name="typeFromValue">The (optional) type derived from the value.</param> /// <param name="typeKind">The expected type kind.</param> /// <returns>The type of the property as derived from the <paramref name="typeFromMetadata"/> and/or <paramref name="typeFromValue"/>.</returns> internal static ResourceType ValidateMetadataType(ResourceType typeFromMetadata, ResourceType typeFromValue, ResourceTypeKind typeKind) { DebugUtils.CheckNoExternalCallers(); if (typeFromMetadata == null) { // if we have no metadata information there is nothing to validate return(typeFromValue); } if (typeFromValue == null) { // derive the property type from the metadata if (typeFromMetadata.ResourceTypeKind != typeKind) { throw new ODataException(Strings.ODataWriter_IncompatibleTypeKind(typeKind.ToString(), typeFromMetadata.Name, typeFromMetadata.ResourceTypeKind.ToString())); } return(typeFromMetadata); } else { // Make sure the types are consistent if (typeFromMetadata.FullName != typeFromValue.FullName) { throw new ODataException(Strings.ODataWriter_IncompatibleType(typeFromValue.FullName, typeFromMetadata.FullName)); } return(typeFromValue); } }
public LazyLoadPropertiesResourceType(Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : base(instanceType, resourceTypeKind, baseType, namespaceName, name, isAbstract) { }
private ResourceType AddDocumentType(MongoContext context, string collectionName, BsonDocument document, ResourceTypeKind resourceTypeKind) { var collectionType = resourceTypeKind == ResourceTypeKind.EntityType ? this.instanceMetadataCache.AddEntityType(collectionName) : this.instanceMetadataCache.AddComplexType(collectionName); bool hasObjectId = false; if (document != null) { foreach (var element in document.Elements) { RegisterResourceProperty(context, collectionType, element); if (IsObjectId(element)) { hasObjectId = true; } } } if (!hasObjectId) { if (resourceTypeKind == ResourceTypeKind.EntityType) { this.instanceMetadataCache.AddKeyProperty(collectionType, MappedObjectIdName, MappedObjectIdType); } AddProviderType(collectionName, ProviderObjectIdName, BsonObjectId.Empty, true); } if (resourceTypeKind == ResourceTypeKind.EntityType) { this.instanceMetadataCache.AddResourceSet(collectionName, collectionType); } return(collectionType); }
public ResourceType (Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) { if (instanceType == null) throw new ArgumentNullException ("instanceType"); if (String.IsNullOrEmpty (name)) throw new ArgumentNullException ("name"); if (resourceTypeKind == ResourceTypeKind.Primitive) throw new ArgumentException ("'Primitive' is not a valid value for resourceTypeKind", "resourceTypeKind"); if (instanceType.IsValueType) throw new ArgumentException ("Clr type for the resource type cannot be a value type."); this.InstanceType = instanceType; this.ResourceTypeKind = resourceTypeKind; this.BaseType = baseType; if (String.IsNullOrEmpty (namespaceName)) this.FullName = name; else this.FullName = namespaceName + "." + name; this.Name = name; this.nameSpace = namespaceName; this.IsAbstract = isAbstract; // Appears to always be true this.CanReflectOnInstanceType = true; }
/// <summary> /// Validates a type name to ensure that it's not an empty string. /// </summary> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="typeName">The type name to validate.</param> /// <param name="typeKind">The expected type kind for the given type name.</param> /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param> /// <returns>The resource type with the given name and kind if the metadata was available, otherwise null.</returns> internal static ResourceType ValidateTypeName(DataServiceMetadataProviderWrapper metadata, string typeName, ResourceTypeKind typeKind, bool isOpenPropertyType) { DebugUtils.CheckNoExternalCallers(); if (typeName == null) { // if we have metadata the type name of an entry or a complex value of an open property must not be null if (metadata != null && (typeKind == ResourceTypeKind.EntityType || isOpenPropertyType)) { throw new ODataException(Strings.ODataWriterCore_MissingTypeNameWithMetadata); } return(null); } // we do not allow empty type names if (typeName.Length == 0) { throw new ODataException(Strings.ODataWriter_TypeNameMustNotBeEmpty); } // If we do have metadata, lookup the type and translate it to ResourceType. ResourceType resourceType = null; if (metadata != null) { resourceType = typeKind == ResourceTypeKind.MultiValue ? ValidateMultiValueTypeName(metadata, typeName) : ValidateNonMultiValueTypeName(metadata, typeName, typeKind); } return(resourceType); }
public ResourceType AddResourceType(string name, ResourceTypeKind resourceTypeKind, bool isOpenType) { return this.AddResourceType(name, "RowEntityType", resourceTypeKind, isOpenType, null, null, false); }
/// <summary> /// returns the new resource type instance /// </summary> /// <param name="type">backing clr type for the resource.</param> /// <param name="kind">kind of the resource.</param> /// <param name="baseType">base type of the resource.</param> /// <param name="metadataCacheItem">Instance of ProviderMetadataCacheItem.</param> /// <returns>returns a new instance of the resource type containing all the metadata.</returns> private static ResourceType CreateResourceType( Type type, ResourceTypeKind kind, ResourceType baseType, ProviderMetadataCacheItem metadataCacheItem) { ResourceType resourceType = new ResourceType(type, kind, baseType, type.Namespace, CommonUtil.GetModelTypeName(type), type.IsAbstract); resourceType.IsOpenType = false; // We need to look at inherited attributes as well so we pass true for inherit argument. if (type.GetCustomAttributes(typeof(HasStreamAttribute), true /* inherit */).Length == 1) { resourceType.IsMediaLinkEntry = true; } // Add stream properties that are marked NamedStream in clrType to resourceType. AddStreamProperties(resourceType, type, baseType == null); metadataCacheItem.AddResourceType(type, resourceType); var childTypes = metadataCacheItem.ChildTypesCache; childTypes.Add(resourceType, null); if (baseType != null) { Debug.Assert(childTypes.ContainsKey(baseType), "childTypes.ContainsKey(baseType)"); if (childTypes[baseType] == null) { childTypes[baseType] = new List<ResourceType>(); } childTypes[baseType].Add(resourceType); } return resourceType; }
private void RegisterResourceProperty(MongoContext context, string collectionName, ResourceType collectionType, Type elementType, BsonElement element, ResourceTypeKind resourceTypeKind) { if (ResolveProviderType(element.Value) == null) return; string propertyName = element.Name; var propertyValue = element.Value; var isKey = false; if (IsObjectId(element)) { propertyName = MongoMetadata.MappedObjectIdName; if (resourceTypeKind == ResourceTypeKind.EntityType) this.dspMetadata.AddKeyProperty(collectionType, propertyName, elementType); else this.dspMetadata.AddPrimitiveProperty(collectionType, propertyName, elementType); isKey = true; } else if (elementType == typeof(BsonDocument)) { ResourceType resourceType = null; var resourceSet = this.dspMetadata.ResourceSets.SingleOrDefault(x => x.Name == propertyName); if (resourceSet != null) { resourceType = resourceSet.ResourceType; } else { resourceType = RegisterResourceType(context, GetComplexTypeName(collectionName, propertyName), element.Value.AsBsonDocument, ResourceTypeKind.ComplexType); } this.dspMetadata.AddComplexProperty(collectionType, propertyName, resourceType); } else if (elementType == typeof(BsonArray)) { var bsonArray = element.Value.AsBsonArray; if (bsonArray != null && bsonArray.Count > 0) { var arrayElement = bsonArray.First(); if (arrayElement.BsonType == BsonType.Document) { ResourceType resourceType = null; var resourceSet = this.dspMetadata.ResourceSets.SingleOrDefault(x => x.Name == propertyName); if (resourceSet != null) { resourceType = resourceSet.ResourceType; } else { resourceType = RegisterResourceType(context, GetCollectionTypeName(collectionName, propertyName), arrayElement.AsBsonDocument, ResourceTypeKind.ComplexType); } this.dspMetadata.AddCollectionProperty(collectionType, propertyName, resourceType); } else { this.dspMetadata.AddCollectionProperty(collectionType, propertyName, arrayElement.RawValue.GetType()); } } } else { this.dspMetadata.AddPrimitiveProperty(collectionType, propertyName, elementType); } if (!string.IsNullOrEmpty(propertyName)) { AddProviderType(collectionName, propertyName, propertyValue, isKey); } }
public ResourceType(Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) { Contract.Requires(instanceType != null); Contract.Requires(resourceTypeKind != ResourceTypeKind.Primitive); Contract.Ensures(!instanceType.IsValueType); }
public ResourceType AddResourceType(string name, string typeName, ResourceTypeKind resourceTypeKind, bool isOpenType, string baseType, string namespaceName, bool isAbstract) { //TODO: Add to existing container (possible?) // add to service container ResourceType baseResourceType = null; if (baseType != null) { foreach (ResourceContainer rc in this.ServiceContainer.ResourceContainers) { foreach (ResourceType rt in rc) { if (rt.Name == baseType) { baseResourceType = rt; break; } } } } ResourceType newResourceType = null; if (baseResourceType == null) newResourceType = Resource.ResourceType(name, namespaceName); else newResourceType = Resource.ResourceType(name, namespaceName, baseResourceType); // call service op to add to metadata string url = this.ServiceUri + String.Format("/AddResourceType?name='{0}'&typeName='{1}'&resourceTypeKind='{2}'&isOpenType={3}" + "{4}{5}&isAbstract=false", name, typeName, resourceTypeKind.ToString(), isOpenType.ToString().ToLowerInvariant(), baseType == null ? "" : "&baseType='" + baseType + "'", namespaceName == null ? "&namespaceName='" + this.ContextNamespace + "'" : "&namespaceName='" + namespaceName + "'"); this.ExecuteServiceOp(url); return newResourceType; }
/// <summary> /// Resolve a type name against the provided metadata. If no type name is given we either throw (if a type name on the value is required, e.g., on entries) /// or infer the type from metadata (if available). /// </summary> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="typeFromMetadata">The type inferred from metadata or null if no metadata is available.</param> /// <param name="typeName">The type name to be resolved.</param> /// <param name="typeKind">The expected type kind of the resolved type.</param> /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param> /// <returns>A resource type for the <paramref name="typeName"/> or null if no metadata is available.</returns> internal static ResourceType ResolveTypeName(DataServiceMetadataProviderWrapper metadata, ResourceType typeFromMetadata, ref string typeName, ResourceTypeKind typeKind, bool isOpenPropertyType) { DebugUtils.CheckNoExternalCallers(); ResourceType typeFromValue = ValidationUtils.ValidateTypeName(metadata, typeName, typeKind, isOpenPropertyType); typeFromValue = ValidationUtils.ValidateMetadataType(typeFromMetadata, typeFromValue, typeKind); // derive the type name from the metadata if available if (typeName == null && typeFromValue != null) { typeName = typeFromValue.FullName; } return(typeFromValue); }
private static string GetResourcePropertyName(BsonElement element, ResourceTypeKind resourceTypeKind) { return IsObjectId(element) && resourceTypeKind != ResourceTypeKind.ComplexType ? MongoMetadata.MappedObjectIdName : NormalizeResourcePropertyName(element.Name); }
public ResourceTypeWithDescription(Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : base(instanceType, resourceTypeKind, baseType, namespaceName, name, isAbstract) { }
/// <summary> /// Validates that <paramref name="typeName"/> is a valid type name of the specified kind (<paramref name="typeKind"/>). /// </summary> /// <param name="metadata">The metadata against which to validate the type name.</param> /// <param name="typeName">The type name to validate.</param> /// <param name="typeKind">The expected <see cref="ResourceTypeKind"/> of the type.</param> /// <returns>A <see cref="ResourceType"/> for the <paramref name="typeName"/>.</returns> internal static ResourceType ValidateNonMultiValueTypeName(DataServiceMetadataProviderWrapper metadata, string typeName, ResourceTypeKind typeKind) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(metadata != null, "metadata != null"); ResourceType resourceType = metadata.TryResolveResourceType(typeName); if (resourceType == null) { throw new ODataException(Strings.ODataWriterCore_UnrecognizedTypeName(typeName, typeKind)); } if (resourceType.ResourceTypeKind != typeKind) { throw new ODataException(Strings.ODataWriterCore_IncorrectTypeKind(typeName, typeKind.ToString(), resourceType.ResourceTypeKind.ToString())); } return resourceType; }
/// <summary> /// Constructs a new instance of Astoria type using the specified clr type /// </summary> /// <param name="instanceType">clr type that represents the flow format inside the Astoria runtime</param> /// <param name="resourceTypeKind"> kind of the resource type</param> /// <param name="baseType">base type of the resource type</param> /// <param name="namespaceName">Namespace name of the given resource type.</param> /// <param name="name">name of the given resource type.</param> /// <param name="isAbstract">whether the resource type is an abstract type or not.</param> public DSPResourceType(Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : base(instanceType, resourceTypeKind, baseType, namespaceName, name, isAbstract) { }
/// <summary>Creates an instance of a data service <see cref="T:Microsoft.OData.Service.Providers.ResourceType" />.</summary> /// <param name="instanceType">CLR type that represents the format inside the WCF Data Services?runtime.</param> /// <param name="resourceTypeKind"> /// <see cref="T:Microsoft.OData.Service.Providers.ResourceTypeKind" /> of the resource type.</param> /// <param name="baseType">Base type of the resource type as string.</param> /// <param name="namespaceName">Namespace name of the resource type as string.</param> /// <param name="name">Name of the given resource type as string.</param> /// <param name="isAbstract">Boolean value that indicates whether the resource type is an abstract type.</param> public ResourceType( Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : this(instanceType, baseType, namespaceName, name, isAbstract) { WebUtil.CheckArgumentNull(instanceType, "instanceType"); WebUtil.CheckStringArgumentNullOrEmpty(name, "name"); WebUtil.CheckResourceTypeKind(resourceTypeKind, "resourceTypeKind"); if (resourceTypeKind == ResourceTypeKind.Primitive || resourceTypeKind == ResourceTypeKind.Collection || resourceTypeKind == Providers.ResourceTypeKind.EntityCollection) { throw new ArgumentException(Strings.ResourceType_InvalidValueForResourceTypeKind("resourceTypeKind"), "resourceTypeKind"); } if (baseType != null && baseType.ResourceTypeKind != resourceTypeKind) { throw new ArgumentException( Strings.ResourceType_InvalidResourceTypeKindInheritance(resourceTypeKind.ToString(), baseType.ResourceTypeKind.ToString()), "resourceTypeKind"); } if (instanceType.IsValueType) { throw new ArgumentException(Strings.ResourceType_TypeCannotBeValueType, "instanceType"); } this.resourceTypeKind = resourceTypeKind; }
internal ResourceType AddResourceType(string name, ResourceTypeKind kind, string typeNamespace, ResourceType baseType, string clrType = null) { name.ThrowIfNullOrEmpty("name", Resources.NullIsPassedAsResourceName, new object[0]); if (typeNamespace == null) { typeNamespace = this.ContainerNamespace; } ResourceType resourceTypeWithDescription = new ResourceTypeWithDescription(typeof(DSResource), kind, baseType, typeNamespace, name, false); resourceTypeWithDescription.CanReflectOnInstanceType = false; resourceTypeWithDescription.CustomState = new ResourceCustomState(clrType); this.ResourceTypes.Add(resourceTypeWithDescription.FullName, resourceTypeWithDescription); return resourceTypeWithDescription; }
/// <summary> /// Constructs a new instance of Resource type for the either given clr primitive type or collection type. /// This constructor must be called only for primitive or collection types. /// </summary> /// <param name="type">The instance type of the resource type.</param> /// <param name="resourceTypeKind"> kind of the resource type</param> /// <param name="namespaceName">namespace of the type.</param> /// <param name="name">name of the type.</param> internal ResourceType(Type type, ResourceTypeKind resourceTypeKind, string namespaceName, string name) : this(type, null, namespaceName, name, false) { Debug.Assert( resourceTypeKind == ResourceTypeKind.Primitive || resourceTypeKind == ResourceTypeKind.Collection || resourceTypeKind == Providers.ResourceTypeKind.EntityCollection, "Only primitive, collection or entity collection resource types can be created by this constructor."); this.resourceTypeKind = resourceTypeKind; this.isReadOnly = true; // Initialize versions - since those are the only mutable fields (lazy init makes them mutable) and primitive types are singletons // so we need to make sure there are no race conditions. switch (resourceTypeKind) { case ResourceTypeKind.Primitive: this.InitializeMetadataAndSchemaVersionForPrimitiveType(); break; case ResourceTypeKind.Collection: this.InitializeMetadataAndSchemaVersionForCollectionType(); break; case ResourceTypeKind.EntityCollection: this.InitializeMetadataAndSchemaVersionForEntityCollectionType(); break; } }
/// <summary> /// Constructs a new instance of Resource type for the given clr primitive type. This constructor must be called only for primitive types. /// </summary> /// <param name="type">clr type representing the primitive type.</param> /// <param name="namespaceName">namespace of the primitive type.</param> /// <param name="name">name of the primitive type.</param> internal ResourceType(Type type, string namespaceName, string name) : this(type, null, namespaceName, name, false) { Debug.Assert(WebUtil.IsPrimitiveType(type), "This constructor should be called only for primitive types"); this.resourceTypeKind = ResourceTypeKind.Primitive; this.isReadOnly = true; }
/// <summary> /// returns the new resource type instance /// </summary> /// <param name="type">backing clr type for the resource.</param> /// <param name="kind">kind of the resource.</param> /// <param name="baseType">base type of the resource.</param> /// <param name="knownTypes">list of already known types</param> /// <param name="childTypes">list of already known types and their immediate children</param> /// <returns>returns a new instance of the resource type containing all the metadata.</returns> private static ResourceType CreateResourceType( Type type, ResourceTypeKind kind, ResourceType baseType, IDictionary<Type, ResourceType> knownTypes, IDictionary<ResourceType, List<ResourceType>> childTypes) { ResourceType resourceType = new ResourceType(type, kind, baseType, type.Namespace, GetModelTypeName(type), type.IsAbstract); resourceType.IsOpenType = false; // We need to look at inherited attributes as well so we pass true for inherit argument. if (type.GetCustomAttributes(typeof(HasStreamAttribute), true /* inherit */).Length == 1) { resourceType.IsMediaLinkEntry = true; } knownTypes.Add(type, resourceType); childTypes.Add(resourceType, null); if (baseType != null) { Debug.Assert(childTypes.ContainsKey(baseType), "childTypes.ContainsKey(baseType)"); if (childTypes[baseType] == null) { childTypes[baseType] = new List<ResourceType>(); } childTypes[baseType].Add(resourceType); } return resourceType; }
private ResourceType AddDocumentType(MongoContext context, string collectionName, BsonDocument document, ResourceTypeKind resourceTypeKind) { var collectionType = resourceTypeKind == ResourceTypeKind.EntityType ? _instanceMetadataCache.AddEntityType(collectionName) : _instanceMetadataCache.AddComplexType(collectionName); bool hasObjectId = false; if (document != null) { foreach (var element in document.Elements) { RegisterResourceProperty(context, collectionType, element); if (IsObjectId(element)) hasObjectId = true; } } if (!hasObjectId) { if (resourceTypeKind == ResourceTypeKind.EntityType) { _instanceMetadataCache.AddKeyProperty(collectionType, MappedObjectIdName, MappedObjectIdType); } AddProviderType(collectionName, ProviderObjectIdName, BsonObjectId.Empty, true); } if (resourceTypeKind == ResourceTypeKind.EntityType) _instanceMetadataCache.AddResourceSet(collectionName, collectionType); return collectionType; }
/// <summary> /// Validates that the (optional) <paramref name="typeFromMetadata"/> is compatible with the (optional) <paramref name="typeFromValue"/>. /// </summary> /// <param name="typeFromMetadata">The (optional) type from the metadata definition.</param> /// <param name="typeFromValue">The (optional) type derived from the value.</param> /// <param name="typeKind">The expected type kind.</param> /// <returns>The type of the property as derived from the <paramref name="typeFromMetadata"/> and/or <paramref name="typeFromValue"/>.</returns> internal static ResourceType ValidateMetadataType(ResourceType typeFromMetadata, ResourceType typeFromValue, ResourceTypeKind typeKind) { DebugUtils.CheckNoExternalCallers(); if (typeFromMetadata == null) { // if we have no metadata information there is nothing to validate return typeFromValue; } if (typeFromValue == null) { // derive the property type from the metadata if (typeFromMetadata.ResourceTypeKind != typeKind) { throw new ODataException(Strings.ODataWriter_IncompatibleTypeKind(typeKind.ToString(), typeFromMetadata.Name, typeFromMetadata.ResourceTypeKind.ToString())); } return typeFromMetadata; } else { // Make sure the types are consistent if (typeFromMetadata.FullName != typeFromValue.FullName) { throw new ODataException(Strings.ODataWriter_IncompatibleType(typeFromValue.FullName, typeFromMetadata.FullName)); } return typeFromValue; } }