GetReferencedTestDescriptorsByName(
            [NotNull] IEnumerable <XmlQualityCondition> referencedConditions,
            [NotNull] XmlDataQualityDocument document)
        {
            IDictionary <string, XmlTestDescriptor> xmlTestDescriptorsByName =
                GetXmlTestDescriptorsByName(document);

            var result = new Dictionary <string, TestDescriptor>(
                StringComparer.OrdinalIgnoreCase);

            foreach (XmlQualityCondition condition in referencedConditions)
            {
                string testDescriptorName = condition.TestDescriptorName;
                if (testDescriptorName == null || result.ContainsKey(testDescriptorName))
                {
                    continue;
                }

                XmlTestDescriptor xmlTestDescriptor;
                if (!xmlTestDescriptorsByName.TryGetValue(testDescriptorName,
                                                          out xmlTestDescriptor))
                {
                    throw new InvalidConfigurationException(
                              string.Format(
                                  "Test descriptor {0}, referenced in quality condition {1}, not found",
                                  testDescriptorName, condition.Name));
                }

                result.Add(testDescriptorName,
                           XmlDataQualityUtils.CreateTestDescriptor(xmlTestDescriptor));
            }

            return(result);
        }
        public static IList <DataSource> GetDataSources(
            [NotNull] XmlDataQualityDocument document,
            [NotNull] XmlQualitySpecification xmlQualitySpecification)
        {
            Assert.ArgumentNotNull(document, nameof(document));
            Assert.ArgumentNotNull(xmlQualitySpecification, nameof(xmlQualitySpecification));

            IList <XmlQualityCondition> referencedConditions =
                XmlDataQualityUtils.GetReferencedXmlQualityConditions(
                    document, new[] { xmlQualitySpecification })
                .Select(p => p.Key)
                .ToList();

            bool hasUndefinedWorkspaceReference;
            IList <XmlWorkspace> xmlWorkspaces = XmlDataQualityUtils.GetReferencedWorkspaces(
                document, referencedConditions, out hasUndefinedWorkspaceReference);

            var result = new List <DataSource>();

            if (hasUndefinedWorkspaceReference)
            {
                result.Add(new DataSource(GetUniqueDefaultName(xmlWorkspaces),
                                          DataSource.AnonymousId));
            }

            result.AddRange(
                xmlWorkspaces.Select(xmlWorkspace => new DataSource(xmlWorkspace)));

            // TODO sort based on reference count?

            return(result);
        }
        private ISpatialReference GetMainSpatialReference(
            [NotNull] Model model,
            [NotNull] string workspaceId,
            [NotNull] IEnumerable <XmlQualityCondition> referencedConditions)
        {
            var spatialDatasetReferenceCount =
                new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase);

            foreach (Dataset dataset in XmlDataQualityUtils.GetReferencedDatasets(
                         model, workspaceId, referencedConditions))
            {
                if (!(dataset is ISpatialDataset))
                {
                    continue;
                }

                if (!spatialDatasetReferenceCount.ContainsKey(dataset.Name))
                {
                    spatialDatasetReferenceCount.Add(dataset.Name, 1);
                }
                else
                {
                    spatialDatasetReferenceCount[dataset.Name]++;
                }
            }

            int    maxReferenceCount = int.MinValue;
            string maxDatasetName    = null;

            foreach (KeyValuePair <string, int> pair in spatialDatasetReferenceCount)
            {
                if (pair.Value <= maxReferenceCount)
                {
                    continue;
                }

                maxReferenceCount = pair.Value;
                maxDatasetName    = pair.Key;
            }

            if (maxDatasetName == null)
            {
                return(null);
            }

            Dataset maxDataset = model.GetDatasetByModelName(maxDatasetName);

            return(maxDataset == null
                                       ? null
                                       : GetSpatialReference(maxDataset));
        }
        private ISpatialReference GetMainSpatialReference(
            [NotNull] Model model,
            [NotNull] string workspaceId,
            [NotNull] IEnumerable <XmlQualityCondition> referencedConditions)
        {
            var spatialDatasetReferenceCount =
                new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase);

            foreach (Dataset dataset in XmlDataQualityUtils.GetReferencedDatasets(
                         model, workspaceId, referencedConditions))
            {
                if (!(dataset is ISpatialDataset))
                {
                    continue;
                }

                if (!spatialDatasetReferenceCount.ContainsKey(dataset.Name))
                {
                    spatialDatasetReferenceCount.Add(dataset.Name, 1);
                }
                else
                {
                    spatialDatasetReferenceCount[dataset.Name]++;
                }
            }

            foreach (KeyValuePair <string, int> pair in
                     spatialDatasetReferenceCount.OrderByDescending(kvp => kvp.Value))
            {
                string datasetName = pair.Key;

                Dataset maxDataset = model.GetDatasetByModelName(datasetName);

                if (maxDataset == null)
                {
                    continue;
                }

                ISpatialReference spatialReference = GetSpatialReference(maxDataset);

                if (spatialReference != null)
                {
                    return(spatialReference);
                }
            }

            return(null);
        }
        private static void AddSubCategories(
            [NotNull] IEnumerable <XmlDataQualityCategory> xmlCategories,
            [NotNull] DataQualityCategory parentCategory,
            [NotNull] IDictionary <XmlDataQualityCategory, DataQualityCategory> result)
        {
            foreach (XmlDataQualityCategory xmlCategory in xmlCategories)
            {
                DataQualityCategory category =
                    XmlDataQualityUtils.CreateDataQualityCategory(xmlCategory, parentCategory);

                result.Add(xmlCategory, category);

                if (xmlCategory.SubCategories != null)
                {
                    AddSubCategories(xmlCategory.SubCategories, category, result);
                }
            }
        }
        private static XmlDataQualityDocument ReadXmlDocument(
            [NotNull] string xml,
            [NotNull] out IList <XmlQualitySpecification> qualitySpecifications)
        {
            Assert.ArgumentNotNullOrEmpty(xml, nameof(xml));

            XmlDataQualityDocument document = XmlDataQualityUtils.DeserializeXml(xml);

            Assert.ArgumentCondition(document.GetAllQualitySpecifications().Any(),
                                     "The document does not contain any quality specifications");

            XmlDataQualityUtils.AssertUniqueQualitySpecificationNames(document);
            XmlDataQualityUtils.AssertUniqueQualityConditionNames(document);
            XmlDataQualityUtils.AssertUniqueTestDescriptorNames(document);

            qualitySpecifications = document.GetAllQualitySpecifications()
                                    .Select(p => p.Key)
                                    .Where(qs => qs.Elements.Count > 0)
                                    .ToList();

            return(document);
        }
        GetCategoryMap([NotNull] XmlDataQualityDocument document)
        {
            var result = new Dictionary <XmlDataQualityCategory, DataQualityCategory>();

            if (document.Categories == null)
            {
                return(result);
            }

            foreach (XmlDataQualityCategory xmlCategory in document.Categories)
            {
                DataQualityCategory category =
                    XmlDataQualityUtils.CreateDataQualityCategory(xmlCategory, null);

                result.Add(xmlCategory, category);

                if (xmlCategory.SubCategories != null)
                {
                    AddSubCategories(xmlCategory.SubCategories, category, result);
                }
            }

            return(result);
        }
        private QualitySpecification CreateQualitySpecificationCore(
            [NotNull] XmlDataQualityDocument document,
            [NotNull] string qualitySpecificationName,
            [NotNull] IEnumerable <DataSource> dataSources,
            bool ignoreConditionsForUnknownDatasets)
        {
            Assert.ArgumentNotNull(document, nameof(document));
            Assert.ArgumentNotNull(dataSources, nameof(dataSources));
            Assert.ArgumentCondition(document.GetAllQualitySpecifications().Any(),
                                     "The document must contain at least one quality specification");

            XmlDataQualityUtils.AssertUniqueWorkspaceIds(document);
            XmlDataQualityUtils.AssertUniqueTestDescriptorNames(document);
            XmlDataQualityUtils.AssertUniqueQualityConditionNames(document);
            XmlDataQualityUtils.AssertUniqueQualitySpecificationNames(document);
            XmlDataQualityUtils.AssertUniqueQualifiedCategoryNames(document);

            XmlDataQualityCategory  xmlSpecificationCategory;
            XmlQualitySpecification xmlQualitySpecification =
                XmlDataQualityUtils.FindXmlQualitySpecification(document,
                                                                qualitySpecificationName,
                                                                out xmlSpecificationCategory);

            Assert.ArgumentCondition(xmlQualitySpecification != null,
                                     "Specification '{0} not found in document",
                                     qualitySpecificationName);

            XmlDataQualityUtils.AssertUniqueElementNames(xmlQualitySpecification);

            IDictionary <XmlDataQualityCategory, DataQualityCategory> categoryMap =
                GetCategoryMap(document);

            IList <KeyValuePair <XmlQualityCondition, XmlDataQualityCategory> >
            referencedXmlConditionPairs =
                XmlDataQualityUtils.GetReferencedXmlQualityConditions(
                    document, new[] { xmlQualitySpecification })
                .ToList();

            IList <XmlQualityCondition> referencedXmlConditions =
                referencedXmlConditionPairs.Select(p => p.Key)
                .ToList();

            IList <XmlWorkspace> referencedXmlWorkspaces =
                XmlDataQualityUtils.GetReferencedWorkspaces(document,
                                                            referencedXmlConditions);

            IDictionary <string, Model> modelsByWorkspaceId = GetModelsByWorkspaceId(
                referencedXmlWorkspaces, dataSources, referencedXmlConditions);

            IDictionary <string, TestDescriptor> testDescriptorsByName =
                GetReferencedTestDescriptorsByName(referencedXmlConditions, document);

            var qualityConditions = new Dictionary <string, QualityCondition>(
                StringComparer.OrdinalIgnoreCase);

            Func <string, IList <Dataset> > getDatasetsByName = name => new List <Dataset>();

            foreach (
                KeyValuePair <XmlQualityCondition, XmlDataQualityCategory> pair in
                referencedXmlConditionPairs)
            {
                XmlQualityCondition    xmlCondition         = pair.Key;
                XmlDataQualityCategory xmlConditionCategory = pair.Value;

                DataQualityCategory conditionCategory = xmlConditionCategory != null
                                                                                ? categoryMap[xmlConditionCategory]
                                                                                : null;

                ICollection <XmlDatasetTestParameterValue> unknownDatasetParameters;
                QualityCondition qualityCondition = XmlDataQualityUtils.CreateQualityCondition(
                    xmlCondition,
                    testDescriptorsByName[xmlCondition.TestDescriptorName],
                    modelsByWorkspaceId,
                    getDatasetsByName,
                    conditionCategory,
                    ignoreConditionsForUnknownDatasets,
                    out unknownDatasetParameters);

                if (qualityCondition == null)
                {
                    Assert.True(ignoreConditionsForUnknownDatasets,
                                "ignoreConditionsForUnknownDatasets");
                    Assert.True(unknownDatasetParameters.Count > 0,
                                "Unexpected number of unknown datasets");

                    _msg.WarnFormat(
                        unknownDatasetParameters.Count == 1
                                                        ? "Quality condition '{0}' is ignored because the following dataset is not found: {1}"
                                                        : "Quality condition '{0}' is ignored because the following datasets are not found: {1}",
                        xmlCondition.Name,
                        XmlDataQualityUtils.ConcatenateUnknownDatasetNames(
                            unknownDatasetParameters,
                            modelsByWorkspaceId,
                            DataSource.AnonymousId));
                }
                else
                {
                    qualityConditions.Add(qualityCondition.Name, qualityCondition);
                }
            }

            DataQualityCategory specificationCategory =
                xmlSpecificationCategory != null
                                        ? categoryMap[xmlSpecificationCategory]
                                        : null;

            return(XmlDataQualityUtils.CreateQualitySpecification(
                       qualityConditions, xmlQualitySpecification, specificationCategory,
                       ignoreConditionsForUnknownDatasets));
        }