예제 #1
0
        /// <summary>
        /// See whether an entity type is defined in one of the schemas in the metadata document.
        /// </summary>
        /// <param name="typeFullName">The qualified name of the entity type.</param>
        /// <param name="document">The document string.</param>
        /// <returns>True if the entity type is defined in the document, false otherwise.</returns>
        bool IsEntityTypeDefinedInDoc(string typeFullName, string document)
        {
            bool     result              = false;
            string   typeSimpleName      = typeFullName.GetLastSegment();
            XElement metaXml             = XElement.Parse(document);
            string   xpath               = string.Format("//*[local-name()='EntityType' and @Name='{0}']", typeSimpleName);
            IEnumerable <XElement> types = metaXml.XPathSelectElements(xpath, ODataNamespaceManager.Instance);

            foreach (XElement type in types)
            {
                AliasNamespacePair aliasAndNamespace = MetadataHelper.GetAliasAndNamespace(type);

                if (
                    string.Format("{0}.{1}", aliasAndNamespace.Alias, typeSimpleName) == typeFullName ||
                    string.Format("{0}.{1}", aliasAndNamespace.Namespace, typeSimpleName) == typeFullName
                    )
                {
                    result = true;
                    break;
                }
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Verify Metadata.Core.4564
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            XElement metaXml = XElement.Parse(context.MetadataDocument);
            string   xpath   = string.Format(@"//*[local-name()='Schema']");
            XElement element = metaXml.XPathSelectElement(xpath, ODataNamespaceManager.Instance);

            AliasNamespacePair aliasNameSpace = MetadataHelper.GetAliasAndNamespace(element);

            // Load MetadataDocument into XMLDOM
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(context.MetadataDocument);

            List <string> typeDefinitionNames = MetadataHelper.GetNamesOfTypeDefinitionByUnderlyingType(context.MetadataDocument, "Edm.Stream");

            List <string> qualifiedTypes = new List <string>();

            foreach (string underlyingType in typeDefinitionNames)
            {
                if (!string.IsNullOrEmpty(aliasNameSpace.Alias))
                {
                    qualifiedTypes.Add(aliasNameSpace.Alias + "." + underlyingType);
                }

                if (!string.IsNullOrEmpty(aliasNameSpace.Namespace))
                {
                    qualifiedTypes.Add(aliasNameSpace.Namespace + "." + underlyingType);
                }
            }

            qualifiedTypes.Add("Edm.Stream");

            foreach (string type in qualifiedTypes)
            {
                // Find all collection that uses Edm.Stream as core type or underlying type.
                xpath = string.Format("//*[@Type = 'Collection({0})']", type);
                XmlNodeList propertyNodeList = xmlDoc.SelectNodes(xpath);

                if (propertyNodeList.Count == 0)
                {
                    passed = true;
                }
                else
                {
                    passed = false;
                    info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                    break;
                }

                // Find non-binding parameter that uses Edm.Stream as type or underlying type.
                xpath            = string.Format("//*[local-name()='Parameter' and @Type='{0}']", type);
                propertyNodeList = xmlDoc.SelectNodes(xpath);

                if (propertyNodeList.Count == 0)
                {
                    passed = true;
                }
                else
                {
                    passed = false;
                    info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                    break;
                }
            }

            return(passed);
        }
        /// <summary>
        /// Verify Metadata.Core.4204
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            // Load MetadataDocument into XMLDOM
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(context.MetadataDocument);
            string      xpath       = "//*[local-name()='Reference']";
            XmlNodeList refNodeList = xmlDoc.SelectNodes(xpath);

            // Add all included reference namespace alias pair in aliasNamespacePairList.
            foreach (XmlNode reference in refNodeList)
            {
                foreach (XmlNode child in reference.ChildNodes)
                {
                    if (child.Attributes == null)
                    {
                        continue;                           // the comment nodes do not contain Attributes collection.
                    }
                    if (child.Name.Equals("edmx:Include"))
                    {
                        string namespaceString = string.Empty;
                        string aliasString     = string.Empty;
                        if (child.Attributes == null)
                        {
                            continue;                           // the comment nodes do not contain Attributes collection.
                        }
                        if (child.Attributes["Namespace"] != null)
                        {
                            namespaceString = child.Attributes["Namespace"].Value;
                        }

                        if (child.Attributes["Alias"] != null)
                        {
                            aliasString = child.Attributes["Alias"].Value;
                        }

                        AliasNamespacePair referenceAliasNamespace = new AliasNamespacePair(aliasString, namespaceString);

                        aliasNamespacePairList.Add(referenceAliasNamespace);
                    }
                }
            }

            XElement metaXml = XElement.Parse(context.MetadataDocument);

            xpath = "//*[local-name()='ComplexType']";
            IEnumerable <XElement> complexTypeElements = metaXml.XPathSelectElements(xpath, ODataNamespaceManager.Instance);

            foreach (XElement complexTypeElement in complexTypeElements)
            {
                passed = true;

                HashSet <string> descendantsSet = new HashSet <string>(StringComparer.Ordinal);

                AliasNamespacePair aliasNameSpace = complexTypeElement.GetAliasAndNamespace();

                if (!string.IsNullOrEmpty(aliasNameSpace.Namespace))
                {
                    descendantsSet.Add(aliasNameSpace.Namespace + "." + complexTypeElement.Attribute("Name").Value);
                }

                if (!string.IsNullOrEmpty(aliasNameSpace.Alias))
                {
                    descendantsSet.Add(aliasNameSpace.Alias + "." + complexTypeElement.Attribute("Name").Value);
                }

                if (!aliasNamespacePairList.Contains(aliasNameSpace))
                {
                    aliasNamespacePairList.Add(aliasNameSpace);
                }

                if (this.IsComplextTypeBaseDeadCycled(complexTypeElement, context, ref descendantsSet))
                {
                    passed = true;
                }
                else
                {
                    passed = false;
                    info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                    break;
                }
            }

            return(passed);
        }
        /// <summary>
        /// Verify Metadata.Core.4561
        /// </summary>
        /// <param name="context">Service context</param>
        /// <param name="info">out parameter to return violation information when rule fail</param>
        /// <returns>true if rule passes; false otherwise</returns>
        public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            bool?passed = null;

            info = null;

            // Load MetadataDocument into XMLDOM
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(context.MetadataDocument);

            List <string> xPathTypes = new List <string>()
            {
                "//*[@Type]",
                "//*[@BaseType]",
                "//*[@UnderlyingType]",
                "//*[@EntityType]",
            };


            List <string> xPathTypesContainPrefix = new List <string> ()
            {
                "//*[starts-with(@Type,'{0}')]",
                "//*[starts-with(@BaseType,'{0}')]",
                "//*[starts-with(@UnderlyingType,'{0}')]",
                "//*[starts-with(@EntityType,'{0}')]",
            };

            XElement metaXml = XElement.Parse(context.MetadataDocument);
            string   xpath   = string.Format(@"//*[local-name()='Schema']");
            IEnumerable <XElement> schemaElements = metaXml.XPathSelectElements(xpath, ODataNamespaceManager.Instance);

            List <string> qualifiedNamePrefixes = new List <string>()
            {
                "Edm.", "Collection(Edm."
            };

            foreach (XElement element in schemaElements)
            {
                AliasNamespacePair aliasNameSpace = MetadataHelper.GetAliasAndNamespace(element);

                if (!string.IsNullOrEmpty(aliasNameSpace.Alias))
                {
                    qualifiedNamePrefixes.Add(aliasNameSpace.Alias + ".");
                    qualifiedNamePrefixes.Add("Collection(" + aliasNameSpace.Alias + ".");
                }

                if (!string.IsNullOrEmpty(aliasNameSpace.Namespace))
                {
                    qualifiedNamePrefixes.Add(aliasNameSpace.Namespace + ".");
                    qualifiedNamePrefixes.Add("Collection(" + aliasNameSpace.Namespace + ".");
                }
            }

            // Add the namespace and alias of the references.
            xpath = "//*[local-name()='Reference']";
            XmlNodeList refNodeList = xmlDoc.SelectNodes(xpath);

            foreach (XmlNode reference in refNodeList)
            {
                foreach (XmlNode child in reference.ChildNodes)
                {
                    if (child.Name.Equals("edmx:Include"))
                    {
                        if (child.Attributes["Alias"] != null)
                        {
                            qualifiedNamePrefixes.Add(child.Attributes["Alias"].Value + ".");
                            qualifiedNamePrefixes.Add("Collection(" + child.Attributes["Alias"].Value + ".");
                        }

                        if (child.Attributes["Namespace"] != null)
                        {
                            qualifiedNamePrefixes.Add(child.Attributes["Namespace"].Value + ".");
                            qualifiedNamePrefixes.Add("Collection(" + child.Attributes["Namespace"].Value + ".");
                        }
                    }
                }
            }

            for (int i = 0; i < 4; i++)
            {
                string      xPathForType = xPathTypes[i];
                XmlNodeList typeNodeList = xmlDoc.SelectNodes(xPathForType);
                int         typeCount    = typeNodeList.Count;
                int         sum          = 0;

                foreach (string qualifiedNamePrefix in qualifiedNamePrefixes)
                {
                    string      xPathfull = string.Format(xPathTypesContainPrefix[i], qualifiedNamePrefix);
                    XmlNodeList containsPrefixNodeList = xmlDoc.SelectNodes(xPathfull);
                    sum += containsPrefixNodeList.Count;
                }

                if (typeCount == sum)
                {
                    passed = true;
                }
                else
                {
                    passed = false;
                    info   = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload);
                    break;
                }
            }

            return(passed);
        }