// <summary>
        // Validates whether facets are declared correctly.
        // </summary>
        // <param name="element"> Schema element being validated. Must not be null. </param>
        // <param name="type"> Resolved type (from declaration on the element). Possibly null. </param>
        // <param name="typeUsageBuilder"> TypeUsageBuilder for the current element. Must not be null. </param>
        internal static void ValidateFacets(SchemaElement element, SchemaType type, TypeUsageBuilder typeUsageBuilder)
        {
            DebugCheck.NotNull(element);
            DebugCheck.NotNull(typeUsageBuilder);

            if (type != null)
            {
                var schemaEnumType = type as SchemaEnumType;
                if (schemaEnumType != null)
                {
                    typeUsageBuilder.ValidateEnumFacets(schemaEnumType);
                }
                else if (!(type is ScalarType)
                         && typeUsageBuilder.HasUserDefinedFacets)
                {
                    Debug.Assert(!(type is SchemaEnumType), "Note that enums should have already been handled.");

                    // Non-scalar type should not have Facets. 
                    element.AddError(
                        ErrorCode.FacetOnNonScalarType, EdmSchemaErrorSeverity.Error, Strings.FacetsOnNonScalarType(type.FQName));
                }
            }
            else
            {
                if (typeUsageBuilder.HasUserDefinedFacets)
                {
                    // Type attribute not specified but facets exist.
                    element.AddError(
                        ErrorCode.IncorrectlyPlacedFacet, EdmSchemaErrorSeverity.Error, Strings.FacetDeclarationRequiresTypeAttribute);
                }
            }
        }
Example #2
0
 internal static string GetTypeNameForErrorMessage(SchemaType type, CollectionKind colKind, bool isRef)
 {
     var typeName = type.FQName;
     if (isRef)
     {
         typeName = "Ref(" + typeName + ")";
     }
     switch (colKind)
     {
         case CollectionKind.Bag:
             typeName = "Collection(" + typeName + ")";
             break;
         default:
             Debug.Assert(colKind == CollectionKind.None, "Unexpected CollectionKind");
             break;
     }
     return typeName;
 }
        // <summary>
        // Validated whether a type is declared correctly.
        // </summary>
        // <param name="element"> Schema element being validated. Must not be null. </param>
        // <param name="type"> Resolved type (from declaration on the element). Possibly null. </param>
        // <param name="typeSubElement"> Child schema element. Possibly null. </param>
        // <remarks>
        // For some elements (e.g. ReturnType) we allow the type to be defined inline in an attribute on the element itself or
        // by using nested elements. These definitions are mutually exclusive.
        // </remarks>
        internal static void ValidateTypeDeclaration(SchemaElement element, SchemaType type, SchemaElement typeSubElement)
        {
            DebugCheck.NotNull(element);

            if (type == null
                && typeSubElement == null)
            {
                //Type not declared as either attribute or subelement
                element.AddError(ErrorCode.TypeNotDeclared, EdmSchemaErrorSeverity.Error, Strings.TypeMustBeDeclared);
            }

            if (type != null
                && typeSubElement != null)
            {
                //Both attribute and sub-element declarations exist
                element.AddError(
                    ErrorCode.TypeDeclaredAsAttributeAndElement, EdmSchemaErrorSeverity.Error, Strings.TypeDeclaredAsAttributeAndElement);
            }
        }
        internal static MetadataItem LoadSchemaElement(
            System.Data.Entity.Core.SchemaObjectModel.SchemaType element,
            DbProviderManifest providerManifest,
            Converter.ConversionCache convertedItemCache,
            Dictionary <SchemaElement, GlobalItem> newGlobalItems)
        {
            GlobalItem globalItem;

            if (newGlobalItems.TryGetValue((SchemaElement)element, out globalItem))
            {
                return((MetadataItem)globalItem);
            }
            System.Data.Entity.Core.SchemaObjectModel.EntityContainer element1 = element as System.Data.Entity.Core.SchemaObjectModel.EntityContainer;
            if (element1 != null)
            {
                return((MetadataItem)Converter.ConvertToEntityContainer(element1, providerManifest, convertedItemCache, newGlobalItems));
            }
            if (element is SchemaEntityType)
            {
                return((MetadataItem)Converter.ConvertToEntityType((SchemaEntityType)element, providerManifest, convertedItemCache, newGlobalItems));
            }
            if (element is Relationship)
            {
                return((MetadataItem)Converter.ConvertToAssociationType((Relationship)element, providerManifest, convertedItemCache, newGlobalItems));
            }
            if (element is SchemaComplexType)
            {
                return((MetadataItem)Converter.ConvertToComplexType((SchemaComplexType)element, providerManifest, convertedItemCache, newGlobalItems));
            }
            if (element is System.Data.Entity.Core.SchemaObjectModel.Function)
            {
                return((MetadataItem)Converter.ConvertToFunction((System.Data.Entity.Core.SchemaObjectModel.Function)element, providerManifest, convertedItemCache, (EntityContainer)null, newGlobalItems));
            }
            if (element is SchemaEnumType)
            {
                return((MetadataItem)Converter.ConvertToEnumType((SchemaEnumType)element, newGlobalItems));
            }
            return((MetadataItem)null);
        }
        // <summary>
        // Validate that reference type is an entity type.
        // </summary>
        // <param name="element"> Schema element being validated. Must not be null. </param>
        // <param name="type"> Resolved type (from declaration on the element). Possibly null. </param>
        internal static void ValidateRefType(SchemaElement element, SchemaType type)
        {
            DebugCheck.NotNull(element);

            if (type != null
                && !(type is SchemaEntityType))
            {
                // Ref type refers to non entity type.
                element.AddError(
                    ErrorCode.ReferenceToNonEntityType, EdmSchemaErrorSeverity.Error, Strings.ReferenceToNonEntityType(type.FQName));
            }
        }
 internal void ValidateDefaultValue(SchemaType type)
 {
     if (null == _default)
     {
         return;
     }
     var scalar = type as ScalarType;
     if (null != scalar)
     {
         ValidateScalarMemberDefaultValue(scalar);
     }
     else
     {
         _element.AddError(ErrorCode.DefaultNotAllowed, EdmSchemaErrorSeverity.Error, Strings.DefaultNotAllowed);
     }
 }
        internal override void ResolveTopLevelNames()
        {
            base.ResolveTopLevelNames();

            if (_type != null)
            {
                return;
            }

            _type = ResolveType(UnresolvedType);

            _typeUsageBuilder.ValidateDefaultValue(_type);

            var scalar = _type as ScalarType;
            if (scalar != null)
            {
                _typeUsageBuilder.ValidateAndSetTypeUsage(scalar, true);
            }
        }
Example #8
0
 protected void TryAddContainer(SchemaType schemaType, bool doNotAddErrorForEmptyName)
 {
     SchemaManager.SchemaTypes.Add(
         schemaType, doNotAddErrorForEmptyName,
         Strings.EntityContainerAlreadyExists);
     SchemaTypes.Add(schemaType);
 }
Example #9
0
        // <summary>
        // validate the following negative scenarios:
        // ReturnType="Collection(EntityTypeA)"
        // ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA"
        // EntitySet="A"
        // ReturnType="Collection(ComplexTypeA)" EntitySet="something"
        // ReturnType="Collection(ComplexTypeA)", but the ComplexTypeA has a nested complexType property, this scenario will be handle in the runtime
        // </summary>
        private void ValidateFunctionImportReturnType(
            SchemaElement owner, SchemaType returnType, EntityContainerEntitySet entitySet, bool entitySetPathDefined)
        {
            // If entity type, verify specification of entity set and that the type is appropriate for the entity set
            var entityType = returnType as SchemaEntityType;

            if (entitySet != null && entitySetPathDefined)
            {
                owner.AddError(
                    ErrorCode.FunctionImportEntitySetAndEntitySetPathDeclared,
                    EdmSchemaErrorSeverity.Error,
                    Strings.FunctionImportEntitySetAndEntitySetPathDeclared(FQName));
            }

            if (null != entityType)
            {
                // entity type
                if (null == entitySet)
                {
                    // ReturnType="Collection(EntityTypeA)"
                    owner.AddError(
                        ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(FQName));
                }
                else if (null != entitySet.EntityType &&
                         !entityType.IsOfType(entitySet.EntityType))
                {
                    // ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA"
                    owner.AddError(
                        ErrorCode.FunctionImportEntityTypeDoesNotMatchEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportEntityTypeDoesNotMatchEntitySet(
                            FQName, entitySet.EntityType.FQName, entitySet.Name));
                }
            }
            else
            {
                // complex type
                var complexType = returnType as SchemaComplexType;
                if (complexType != null)
                {
                    if (entitySet != null || entitySetPathDefined)
                    {
                        // ReturnType="Collection(ComplexTypeA)" EntitySet="something"
                        owner.AddError(
                            ErrorCode.ComplexTypeAsReturnTypeAndDefinedEntitySet,
                            EdmSchemaErrorSeverity.Error,
                            owner.LineNumber,
                            owner.LinePosition,
                            Strings.ComplexTypeAsReturnTypeAndDefinedEntitySet(FQName, complexType.Name));
                    }
                }
                else
                {
                    Debug.Assert(
                        returnType == null || returnType is ScalarType || returnType is SchemaEnumType || returnType is Relationship,
                        "null return type, scalar return type, enum return type or relationship expected here.");

                    // scalar type or no return type
                    if (entitySet != null || entitySetPathDefined)
                    {
                        // EntitySet="A"
                        owner.AddError(
                            ErrorCode.FunctionImportSpecifiesEntitySetButDoesNotReturnEntityType,
                            EdmSchemaErrorSeverity.Error,
                            Strings.FunctionImportSpecifiesEntitySetButNotEntityType(FQName));
                    }
                }
            }
        }
Example #10
0
        // <summary>
        // Look up a fully qualified type name reference.
        // </summary>
        // <param name="usingElement"> element containing the reference </param>
        // <param name="typeName"> the fully qualified type name </param>
        // <param name="type"> the referenced schema type </param>
        // <returns> false if there was an error </returns>
        internal bool ResolveTypeName(SchemaElement usingElement, string typeName, out SchemaType type)
        {
            DebugCheck.NotNull(usingElement);
            DebugCheck.NotNull(typeName);

            type = null;

            // get the schema(s) that match the namespace/alias
            string actualQualification;
            string unqualifiedTypeName;

            Utils.ExtractNamespaceAndName(typeName, out actualQualification, out unqualifiedTypeName);
            var definingQualification = actualQualification;

            if (definingQualification == null)
            {
                definingQualification = ProviderManifest == null ? _namespaceName : ProviderManifest.NamespaceName;
            }

            string namespaceName;

            // First check if there is an alias defined by this name. For primitive type namespace, we do not need to resolve
            // any alias, since that's a reserved keyword and we don't allow alias with that name
            if (actualQualification == null ||
                !AliasResolver.TryResolveAlias(definingQualification, out namespaceName))
            {
                namespaceName = definingQualification;
            }

            // Resolve the type name
            if (!SchemaManager.TryResolveType(namespaceName, unqualifiedTypeName, out type))
            {
                // it must be an undefined type.
                if (actualQualification == null)
                {
                    // Every type except the primitive type must be qualified
                    usingElement.AddError(ErrorCode.NotInNamespace, EdmSchemaErrorSeverity.Error, Strings.NotNamespaceQualified(typeName));
                }
                else if (!SchemaManager.IsValidNamespaceName(namespaceName))
                {
                    usingElement.AddError(
                        ErrorCode.BadNamespace, EdmSchemaErrorSeverity.Error, Strings.BadNamespaceOrAlias(actualQualification));
                }
                else
                {
                    // if the type name was alias qualified
                    if (namespaceName != definingQualification)
                    {
                        usingElement.AddError(
                            ErrorCode.NotInNamespace, EdmSchemaErrorSeverity.Error,
                            Strings.NotInNamespaceAlias(unqualifiedTypeName, namespaceName, definingQualification));
                    }
                    else
                    {
                        usingElement.AddError(
                            ErrorCode.NotInNamespace, EdmSchemaErrorSeverity.Error,
                            Strings.NotInNamespaceNoAlias(unqualifiedTypeName, namespaceName));
                    }
                }
                return(false);
            }
            // For ssdl and provider manifest, make sure that the type is present in this schema or primitive schema
            else if (DataModel != SchemaDataModelOption.EntityDataModel &&
                     type.Schema != this &&
                     type.Schema != SchemaManager.PrimitiveSchema)
            {
                Debug.Assert(type.Namespace != Namespace, "Using element is not allowed in the schema of ssdl and provider manifest");
                usingElement.AddError(
                    ErrorCode.InvalidNamespaceOrAliasSpecified, EdmSchemaErrorSeverity.Error,
                    Strings.InvalidNamespaceOrAliasSpecified(actualQualification));
                return(false);
            }

            return(true);
        }
        internal static MetadataItem LoadSchemaElement(
            SchemaType element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<SchemaElement, GlobalItem> newGlobalItems)
        {
            DebugCheck.NotNull(providerManifest);
            // Try to fetch from the collection first
            GlobalItem item;

            Debug.Assert(
                !convertedItemCache.ItemCollection.TryGetValue(element.FQName, false, out item),
                "Som should have checked for duplicate items");

            // Try to fetch in our collection of new GlobalItems
            if (newGlobalItems.TryGetValue(element, out item))
            {
                return item;
            }

            var entityContainer = element as SchemaObjectModel.EntityContainer;
            // Perform different conversion depending on the type of the SOM object
            if (entityContainer != null)
            {
                item = ConvertToEntityContainer(
                    entityContainer,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is SchemaEntityType)
            {
                item = ConvertToEntityType(
                    (SchemaEntityType)element,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is Relationship)
            {
                item = ConvertToAssociationType(
                    (Relationship)element,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is SchemaComplexType)
            {
                item = ConvertToComplexType(
                    (SchemaComplexType)element,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is Function)
            {
                item = ConvertToFunction(
                    (Function)element, providerManifest,
                    convertedItemCache, null, newGlobalItems);
            }
            else if (element is SchemaEnumType)
            {
                item = ConvertToEnumType((SchemaEnumType)element, newGlobalItems);
            }
            else
            {
                // the only type we don't handle is the ProviderManifest TypeElement
                // if it is anything else, it is probably a mistake
                Debug.Assert(
                    element is TypeElement &&
                    element.Schema.DataModel == SchemaDataModelOption.ProviderManifestModel,
                    "Unknown Type in somschema");
                return null;
            }

            return item;
        }
        private static TypeUsage GetFunctionTypeUsage(
            bool isModelFunction,
            Function somFunction,
            FacetEnabledSchemaElement somParameter,
            DbProviderManifest providerManifest,
            bool areConvertingForProviderManifest,
            SchemaType type,
            CollectionKind collectionKind,
            bool isRefType,
            ConversionCache convertedItemCache,
            Dictionary<SchemaElement, GlobalItem> newGlobalItems)
        {
            if (null != somParameter
                && areConvertingForProviderManifest
                && somParameter.HasUserDefinedFacets)
            {
                return somParameter.TypeUsage;
            }

            if (null == type)
            {
                if (isModelFunction
                    && somParameter != null
                    && somParameter is Parameter)
                {
                    ((Parameter)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return somParameter.TypeUsage;
                }
                else if (somParameter != null
                         && somParameter is ReturnType)
                {
                    ((ReturnType)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return somParameter.TypeUsage;
                }
                else
                {
                    return null;
                }
            }

            EdmType edmType;
            if (!areConvertingForProviderManifest)
            {
                // SOM verifies the type is either scalar, row, or entity
                var scalarType = type as ScalarType;
                if (null != scalarType)
                {
                    if (isModelFunction && somParameter != null)
                    {
                        if (somParameter.TypeUsage == null)
                        {
                            somParameter.ValidateAndSetTypeUsage(scalarType);
                        }
                        return somParameter.TypeUsage;
                    }
                    else if (isModelFunction)
                    {
                        var modelFunction = somFunction as ModelFunction;
                        if (modelFunction.TypeUsage == null)
                        {
                            modelFunction.ValidateAndSetTypeUsage(scalarType);
                        }
                        return modelFunction.TypeUsage;
                    }
                    else if (somParameter != null
                             && somParameter.HasUserDefinedFacets
                             && somFunction.Schema.DataModel == SchemaDataModelOption.ProviderDataModel)
                    {
                        somParameter.ValidateAndSetTypeUsage(scalarType);
                        return somParameter.TypeUsage;
                    }
                    else
                    {
                        edmType = GetPrimitiveType(scalarType, providerManifest);
                    }
                }
                else
                {
                    edmType = (EdmType)LoadSchemaElement(
                        type,
                        providerManifest,
                        convertedItemCache,
                        newGlobalItems);

                    // Neither FunctionImport nor its Parameters can have facets when defined in CSDL so for enums, 
                    // since they are only a CSpace concept, we need to process facets only on model functions 
                    if (isModelFunction && type is SchemaEnumType)
                    {
                        Debug.Assert(somFunction.Schema.DataModel == SchemaDataModelOption.EntityDataModel, "Enums live only in CSpace");

                        if (somParameter != null)
                        {
                            somParameter.ValidateAndSetTypeUsage(edmType);
                            return somParameter.TypeUsage;
                        }
                        else if (somFunction != null)
                        {
                            var modelFunction = ((ModelFunction)somFunction);
                            modelFunction.ValidateAndSetTypeUsage(edmType);
                            return modelFunction.TypeUsage;
                        }
                        else
                        {
                            Debug.Fail("Should never get here.");
                        }
                    }
                }
            }
            else if (type is TypeElement)
            {
                var typeElement = type as TypeElement;
                edmType = typeElement.PrimitiveType;
            }
            else
            {
                var typeElement = type as ScalarType;
                edmType = typeElement.Type;
            }

            //Construct type usage
            TypeUsage usage;
            if (collectionKind != CollectionKind.None)
            {
                usage = convertedItemCache.GetCollectionTypeUsageWithNullFacets(edmType);
            }
            else
            {
                var entityType = edmType as EntityType;
                if (entityType != null && isRefType)
                {
                    usage = TypeUsage.Create(new RefType(entityType));
                }
                else
                {
                    usage = convertedItemCache.GetTypeUsageWithNullFacets(edmType);
                }
            }

            return usage;
        }
        private static TypeUsage GetFunctionTypeUsage(
            bool isModelFunction,
            System.Data.Entity.Core.SchemaObjectModel.Function somFunction,
            FacetEnabledSchemaElement somParameter,
            DbProviderManifest providerManifest,
            bool areConvertingForProviderManifest,
            System.Data.Entity.Core.SchemaObjectModel.SchemaType type,
            CollectionKind collectionKind,
            bool isRefType,
            Converter.ConversionCache convertedItemCache,
            Dictionary <SchemaElement, GlobalItem> newGlobalItems)
        {
            if (somParameter != null && areConvertingForProviderManifest && somParameter.HasUserDefinedFacets)
            {
                return(somParameter.TypeUsage);
            }
            if (type == null)
            {
                if (isModelFunction && somParameter != null && somParameter is Parameter)
                {
                    ((Parameter)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return(somParameter.TypeUsage);
                }
                if (somParameter == null || !(somParameter is ReturnType))
                {
                    return((TypeUsage)null);
                }
                ((ReturnType)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                return(somParameter.TypeUsage);
            }
            EdmType edmType;

            if (!areConvertingForProviderManifest)
            {
                ScalarType scalarType = type as ScalarType;
                if (scalarType != null)
                {
                    if (isModelFunction && somParameter != null)
                    {
                        if (somParameter.TypeUsage == null)
                        {
                            somParameter.ValidateAndSetTypeUsage(scalarType);
                        }
                        return(somParameter.TypeUsage);
                    }
                    if (isModelFunction)
                    {
                        ModelFunction modelFunction = somFunction as ModelFunction;
                        if (modelFunction.TypeUsage == null)
                        {
                            modelFunction.ValidateAndSetTypeUsage(scalarType);
                        }
                        return(modelFunction.TypeUsage);
                    }
                    if (somParameter != null && somParameter.HasUserDefinedFacets && somFunction.Schema.DataModel == SchemaDataModelOption.ProviderDataModel)
                    {
                        somParameter.ValidateAndSetTypeUsage(scalarType);
                        return(somParameter.TypeUsage);
                    }
                    edmType = (EdmType)Converter.GetPrimitiveType(scalarType, providerManifest);
                }
                else
                {
                    edmType = (EdmType)Converter.LoadSchemaElement(type, providerManifest, convertedItemCache, newGlobalItems);
                    if (isModelFunction && type is SchemaEnumType)
                    {
                        if (somParameter != null)
                        {
                            somParameter.ValidateAndSetTypeUsage(edmType);
                            return(somParameter.TypeUsage);
                        }
                        if (somFunction != null)
                        {
                            ModelFunction modelFunction = (ModelFunction)somFunction;
                            modelFunction.ValidateAndSetTypeUsage(edmType);
                            return(modelFunction.TypeUsage);
                        }
                    }
                }
            }
            else
            {
                edmType = !(type is TypeElement) ? (EdmType)(type as ScalarType).Type : (EdmType)(type as TypeElement).PrimitiveType;
            }
            TypeUsage typeUsage;

            if (collectionKind != CollectionKind.None)
            {
                typeUsage = convertedItemCache.GetCollectionTypeUsageWithNullFacets(edmType);
            }
            else
            {
                EntityType entityType = edmType as EntityType;
                typeUsage = entityType == null || !isRefType?convertedItemCache.GetTypeUsageWithNullFacets(edmType) : TypeUsage.Create((EdmType) new RefType(entityType));
            }
            return(typeUsage);
        }
        /// <summary>
        ///     Resolve the type - if the type is not found, return appropriate error
        /// </summary>
        /// <returns> </returns>
        public bool TryResolveType(string namespaceName, string typeName, out SchemaType schemaType)
        {
            // For resolving entity container names, namespace can be null
            var fullyQualifiedName = String.IsNullOrEmpty(namespaceName) ? typeName : namespaceName + "." + typeName;

            schemaType = SchemaTypes.LookUpEquivalentKey(fullyQualifiedName);
            if (schemaType != null)
            {
                return true;
            }

            return false;
        }
 private void ValidateFunctionImportReturnType(
     SchemaElement owner, SchemaType returnType, CollectionKind returnTypeCollectionKind, EntityContainerEntitySet entitySet,
     bool entitySetPathDefined)
 {
     if (returnType != null
         && !ReturnTypeMeetsFunctionImportBasicRequirements(returnType, returnTypeCollectionKind))
     {
         owner.AddError(
             ErrorCode.FunctionImportUnsupportedReturnType,
             EdmSchemaErrorSeverity.Error,
             owner,
             GetReturnTypeErrorMessage(Name)
             );
     }
     ValidateFunctionImportReturnType(owner, returnType, entitySet, entitySetPathDefined);
 }
 internal override void ResolveTopLevelNames()
 {
     // if the underlying type was not specified in the CSDL we use int by default
     if (_unresolvedUnderlyingTypeName == null)
     {
         _underlyingType = Schema.SchemaManager.SchemaTypes
                                 .Single(t => t is ScalarType && ((ScalarType)t).TypeKind == PrimitiveTypeKind.Int32);
     }
     else
     {
         Debug.Assert(_unresolvedUnderlyingTypeName != string.Empty);
         Schema.ResolveTypeName(this, _unresolvedUnderlyingTypeName, out _underlyingType);
     }
 }
        private bool ReturnTypeMeetsFunctionImportBasicRequirements(SchemaType type, CollectionKind returnTypeCollectionKind)
        {
            if (type is ScalarType
                && returnTypeCollectionKind == CollectionKind.Bag)
            {
                return true;
            }
            if (type is SchemaEntityType
                && returnTypeCollectionKind == CollectionKind.Bag)
            {
                return true;
            }

            if (Schema.SchemaVersion
                == XmlConstants.EdmVersionForV1_1)
            {
                if (type is ScalarType
                    && returnTypeCollectionKind == CollectionKind.None)
                {
                    return true;
                }
                if (type is SchemaEntityType
                    && returnTypeCollectionKind == CollectionKind.None)
                {
                    return true;
                }
                if (type is SchemaComplexType
                    && returnTypeCollectionKind == CollectionKind.None)
                {
                    return true;
                }
                if (type is SchemaComplexType
                    && returnTypeCollectionKind == CollectionKind.Bag)
                {
                    return true;
                }
            }
            if (Schema.SchemaVersion
                >= XmlConstants.EdmVersionForV2)
            {
                if (type is SchemaComplexType
                    && returnTypeCollectionKind == CollectionKind.Bag)
                {
                    return true;
                }
            }
            if (Schema.SchemaVersion
                >= XmlConstants.EdmVersionForV3)
            {
                if (type is SchemaEnumType
                    && returnTypeCollectionKind == CollectionKind.Bag)
                {
                    return true;
                }
            }

            return false;
        }
Example #18
0
 protected void TryAddType(SchemaType schemaType, bool doNotAddErrorForEmptyName)
 {
     SchemaManager.SchemaTypes.Add(
         schemaType, doNotAddErrorForEmptyName,
         Strings.TypeNameAlreadyDefinedDuplicate);
     SchemaTypes.Add(schemaType);
 }
        /// <summary>
        ///     validate the following negative scenarios:
        ///     ReturnType="Collection(EntityTypeA)"
        ///     ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA"
        ///     EntitySet="A"
        ///     ReturnType="Collection(ComplexTypeA)" EntitySet="something"
        ///     ReturnType="Collection(ComplexTypeA)", but the ComplexTypeA has a nested complexType property, this scenario will be handle in the runtime
        /// </summary>
        private void ValidateFunctionImportReturnType(
            SchemaElement owner, SchemaType returnType, EntityContainerEntitySet entitySet, bool entitySetPathDefined)
        {
            // If entity type, verify specification of entity set and that the type is appropriate for the entity set
            var entityType = returnType as SchemaEntityType;

            if (entitySet != null && entitySetPathDefined)
            {
                owner.AddError(
                    ErrorCode.FunctionImportEntitySetAndEntitySetPathDeclared,
                    EdmSchemaErrorSeverity.Error,
                    Strings.FunctionImportEntitySetAndEntitySetPathDeclared(FQName));
            }

            if (null != entityType)
            {
                // entity type
                if (null == entitySet)
                {
                    // ReturnType="Collection(EntityTypeA)"
                    owner.AddError(
                        ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(FQName));
                }
                else if (null != entitySet.EntityType
                         && !entityType.IsOfType(entitySet.EntityType))
                {
                    // ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA"
                    owner.AddError(
                        ErrorCode.FunctionImportEntityTypeDoesNotMatchEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportEntityTypeDoesNotMatchEntitySet(
                            FQName, entitySet.EntityType.FQName, entitySet.Name));
                }
            }
            else
            {
                // complex type
                var complexType = returnType as SchemaComplexType;
                if (complexType != null)
                {
                    if (entitySet != null || entitySetPathDefined)
                    {
                        // ReturnType="Collection(ComplexTypeA)" EntitySet="something"
                        owner.AddError(
                            ErrorCode.ComplexTypeAsReturnTypeAndDefinedEntitySet,
                            EdmSchemaErrorSeverity.Error,
                            owner.LineNumber,
                            owner.LinePosition,
                            Strings.ComplexTypeAsReturnTypeAndDefinedEntitySet(FQName, complexType.Name));
                    }
                }
                else
                {
                    Debug.Assert(
                        returnType == null || returnType is ScalarType || returnType is SchemaEnumType || returnType is Relationship,
                        "null return type, scalar return type, enum return type or relationship expected here.");

                    // scalar type or no return type
                    if (entitySet != null || entitySetPathDefined)
                    {
                        // EntitySet="A"
                        owner.AddError(
                            ErrorCode.FunctionImportSpecifiesEntitySetButDoesNotReturnEntityType,
                            EdmSchemaErrorSeverity.Error,
                            Strings.FunctionImportSpecifiesEntitySetButNotEntityType(FQName));
                    }
                }
            }
        }
Example #20
0
        // <summary>
        // Look up a fully qualified type name reference.
        // </summary>
        // <param name="usingElement"> element containing the reference </param>
        // <param name="typeName"> the fully qualified type name </param>
        // <param name="type"> the referenced schema type </param>
        // <returns> false if there was an error </returns>
        internal bool ResolveTypeName(SchemaElement usingElement, string typeName, out SchemaType type)
        {
            DebugCheck.NotNull(usingElement);
            DebugCheck.NotNull(typeName);

            type = null;

            // get the schema(s) that match the namespace/alias
            string actualQualification;
            string unqualifiedTypeName;
            Utils.ExtractNamespaceAndName(typeName, out actualQualification, out unqualifiedTypeName);
            var definingQualification = actualQualification;

            if (definingQualification == null)
            {
                definingQualification = ProviderManifest == null ? _namespaceName : ProviderManifest.NamespaceName;
            }

            string namespaceName;
            // First check if there is an alias defined by this name. For primitive type namespace, we do not need to resolve
            // any alias, since that's a reserved keyword and we don't allow alias with that name
            if (actualQualification == null
                || !AliasResolver.TryResolveAlias(definingQualification, out namespaceName))
            {
                namespaceName = definingQualification;
            }

            // Resolve the type name
            if (!SchemaManager.TryResolveType(namespaceName, unqualifiedTypeName, out type))
            {
                // it must be an undefined type.
                if (actualQualification == null)
                {
                    // Every type except the primitive type must be qualified
                    usingElement.AddError(ErrorCode.NotInNamespace, EdmSchemaErrorSeverity.Error, Strings.NotNamespaceQualified(typeName));
                }
                else if (!SchemaManager.IsValidNamespaceName(namespaceName))
                {
                    usingElement.AddError(
                        ErrorCode.BadNamespace, EdmSchemaErrorSeverity.Error, Strings.BadNamespaceOrAlias(actualQualification));
                }
                else
                {
                    // if the type name was alias qualified
                    if (namespaceName != definingQualification)
                    {
                        usingElement.AddError(
                            ErrorCode.NotInNamespace, EdmSchemaErrorSeverity.Error,
                            Strings.NotInNamespaceAlias(unqualifiedTypeName, namespaceName, definingQualification));
                    }
                    else
                    {
                        usingElement.AddError(
                            ErrorCode.NotInNamespace, EdmSchemaErrorSeverity.Error,
                            Strings.NotInNamespaceNoAlias(unqualifiedTypeName, namespaceName));
                    }
                }
                return false;
            }
            // For ssdl and provider manifest, make sure that the type is present in this schema or primitive schema
            else if (DataModel != SchemaDataModelOption.EntityDataModel
                     && type.Schema != this
                     && type.Schema != SchemaManager.PrimitiveSchema)
            {
                Debug.Assert(type.Namespace != Namespace, "Using element is not allowed in the schema of ssdl and provider manifest");
                usingElement.AddError(
                    ErrorCode.InvalidNamespaceOrAliasSpecified, EdmSchemaErrorSeverity.Error,
                    Strings.InvalidNamespaceOrAliasSpecified(actualQualification));
                return false;
            }

            return true;
        }
Example #21
0
 private bool ReturnTypeMeetsFunctionImportBasicRequirements(
     SchemaType type,
     CollectionKind returnTypeCollectionKind)
 {
     return(type is ScalarType && returnTypeCollectionKind == CollectionKind.Bag || type is SchemaEntityType && returnTypeCollectionKind == CollectionKind.Bag || this.Schema.SchemaVersion == 1.1 && (type is ScalarType && returnTypeCollectionKind == CollectionKind.None || type is SchemaEntityType && returnTypeCollectionKind == CollectionKind.None || (type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.None || type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.Bag)) || (this.Schema.SchemaVersion >= 2.0 && type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.Bag || this.Schema.SchemaVersion >= 3.0 && type is SchemaEnumType && returnTypeCollectionKind == CollectionKind.Bag));
 }