예제 #1
0
        /// <summary>
        /// Validates the instance, declared and stated profiles for consistenty.
        /// </summary>
        /// <returns></returns>
        public OperationOutcome Validate()
        {
            if (_lastValidationOutcome != null)
            {
                return(_lastValidationOutcome);
            }

            var outcome = new OperationOutcome();

            // Resolve input profiles first (note: this is cached)
            var resolutionOutcome = Resolve();

            if (!resolutionOutcome.Success)
            {
                return(resolutionOutcome);
            }
            else
            {
                outcome.Add(resolutionOutcome);
            }

            // If we have an instance type, it should be compatible with the declared type on the definition and the stated profiles
            if (InstanceType != null)
            {
                if (DeclaredType != null)
                {
                    if (!ModelInfo.IsInstanceTypeFor(DeclaredType.BaseType(), InstanceType.BaseType()))
                    {
                        outcome.AddIssue($"The declared type of the element ({DeclaredType.ReadableName()}) is incompatible with that of the instance ('{InstanceType.ReadableName()}')",
                                         Issue.CONTENT_ELEMENT_HAS_INCORRECT_TYPE, _path);
                    }
                }

                foreach (var type in StatedProfiles)
                {
                    if (!ModelInfo.IsInstanceTypeFor(type.BaseType(), InstanceType.BaseType()))
                    {
                        outcome.AddIssue($"Instance of type '{InstanceType.ReadableName()}' is incompatible with the stated profile '{type.Url}' which is constraining constrained type '{type.ReadableName()}'",
                                         Issue.CONTENT_ELEMENT_HAS_INCORRECT_TYPE, _path);
                    }
                }
            }

            // All stated profiles should be profiling the same core type
            if (StatedProfiles.Any())
            {
                var baseTypes = StatedProfiles.Select(p => p.BaseType()).Distinct().ToList();

                if (baseTypes.Count > 1)
                {
                    var combinedNames = String.Join(" and ", baseTypes.Select(bt => bt.GetLiteral()));
                    outcome.AddIssue($"The stated profiles are constraints on multiple different core types ({combinedNames}), which can never be satisfied.",
                                     Issue.CONTENT_MISMATCHING_PROFILES, _path);
                }
                else
                {
                    // The stated profiles should be compatible with the declared type of the element
                    if (DeclaredType != null)
                    {
                        if (!ModelInfo.IsInstanceTypeFor(DeclaredType.BaseType(), baseTypes.Single()))
                        {
                            outcome.AddIssue($"The stated profiles are all constraints on '{baseTypes.Single()}', which is incompatible with the declared type '{DeclaredType.ReadableName()}' of the element",
                                             Issue.CONTENT_MISMATCHING_PROFILES, _path);
                        }
                    }
                }
            }

            _lastValidationOutcome = outcome;
            return(outcome);
        }