Example #1
0
        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);
        }
Example #2
0
        /// <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;
        }
Example #3
0
 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;
        }
Example #5
0
        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()));
        }
Example #6
0
        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);
        }
Example #7
0
 /// <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);
     }
 }
Example #8
0
 public ResourceTypeMapping(
     Type clientClrType,
     ResourceTypeKind resourceTypeKind,
     ResourceTypeMapping baseType,
     string namespaceName,
     string name,
     bool isAbstract)
     : base(clientClrType, resourceTypeKind, baseType, namespaceName, name, isAbstract)
 {
 }
Example #9
0
 /// <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>();
 }
Example #10
0
 /// <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>();
 }
Example #11
0
        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);
        }
Example #12
0
        /// <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;
        }
Example #13
0
        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);
        }
Example #14
0
        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);
        }
Example #15
0
        /// <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);
        }
Example #16
0
        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);
        }
Example #17
0
        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));
        }
Example #18
0
        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;
        }
Example #19
0
        /// <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;
        }
Example #20
0
        /// <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));
 }
Example #24
0
        /// <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);
        }
Example #25
0
        /// <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);
            }
        }
Example #26
0
 public LazyLoadPropertiesResourceType(Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract)
     : base(instanceType, resourceTypeKind, baseType, namespaceName, name, isAbstract)
 {
 }
Example #27
0
        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);
        }
Example #28
0
		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;
		}
Example #29
0
        /// <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);
        }
Example #30
0
 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;
        }
Example #32
0
        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);
 }
Example #34
0
        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;
        }
Example #35
0
        /// <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);
        }
Example #36
0
 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)
 {
 }
Example #38
0
        /// <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;
        }
Example #39
0
 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);
 }
Example #40
0
		/// <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);
			}
		}
Example #41
0
 /// <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)
 {
 }
		public ResourceTypeWithDescription(Type instanceType, ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : base(instanceType, resourceTypeKind, baseType, namespaceName, name, isAbstract)
		{
		}
Example #43
0
        /// <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;
        }
Example #44
0
		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;
		}
Example #45
0
 /// <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)
 {
 }
Example #46
0
        /// <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;
            }
        }
Example #47
0
 /// <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;
        }
Example #49
0
        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;
        }
Example #50
0
		/// <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;
		}
Example #51
0
		/// <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;
		}
Example #52
0
        /// <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;
            }
        }