public void ValidateCollections(Profile profile, Resource resource)
        {
            var domainResource = GetDomainResourceFor(resource);

            if (domainResource == null)
            {
                throw new InvalidResourceException(resource, profile);
            }

            foreach (var collectionElement in GetValidationElements(profile, resource, "Collection"))
            {
                var collectionName  = GetValidationElementName(collectionElement);
                var containingTable = GetContainingTable(collectionElement, resource);

                var embeddedObjectCollections = domainResource.EmbeddedObjects.ToDictionary(
                    embeddedObj => embeddedObj.ObjectType.Name,
                    embeddedObj => embeddedObj.ObjectType.Collections.Select(
                        embeddedObjectCollection => embeddedObjectCollection.PropertyName));

                var invalidCollections =
                    containingTable == resource.name && !domainResource.Collections
                    .Select(domainResourceCollection => domainResourceCollection.PropertyName)
                    .Contains(collectionName) ||
                    containingTable != resource.name && embeddedObjectCollections.Any(
                        embeddedObjectCollection => embeddedObjectCollection.Key == containingTable &&
                        !embeddedObjectCollection.Value.Contains(collectionName));

                if (invalidCollections)
                {
                    throw new MissingForeignKeyException("Collection", collectionName, profile, domainResource.Name);
                }
            }
        }
        public void ValidateProperties(Profile profile, Resource resource)
        {
            var domainResource = GetDomainResourceFor(resource);

            foreach (var propertyElement in GetValidationElements(profile, resource, "Property"))
            {
                var propertyName = GetValidationElementName(propertyElement);

                if (IsReferenceProperty(propertyName))
                {
                    if (!domainResource.References.Any(
                            reference => reference.PropertyName == propertyName &&
                            reference.ParentFullName.Name == GetContainingTable(propertyElement, resource)))
                    {
                        throw new IncomingReferenceException(propertyName, profile, domainResource.Name);
                    }

                    return;
                }

                var resourceProperty = domainResource.AllProperties
                                       .Concat(domainResource.AllContainedItemTypes.SelectMany(item => item.AllProperties))
                                       .Concat(domainResource.Extensions.SelectMany(p => p.ObjectType.AllProperties))
                                       .FirstOrDefault(
                    domainResourceProperty => domainResourceProperty.PropertyName ==
                    FormatPropertyNameAsResourcePropertyName(propertyName));

                if (resourceProperty == null)
                {
                    throw new MissingPropertyException(propertyName, profile);
                }

                if (resourceProperty.IsLookup)
                {
                    var invalidPropertyReference = !resourceProperty.IsIdentifying && resourceProperty.IsLookup &&
                                                   resourceProperty.EntityProperty.Entity.IncomingAssociations
                                                   .Concat(resourceProperty.EntityProperty.Entity.OutgoingAssociations)
                                                   .Any(
                        association
                        => association.ThisProperties.Contains(
                            resourceProperty.EntityProperty) &&
                        !resourceProperty.IsDirectLookup);

                    if (invalidPropertyReference)
                    {
                        throw new InvalidPropertyReferenceException(
                                  propertyName,
                                  profile,
                                  domainResource.Name,
                                  resourceProperty.ParentFullName.Name);
                    }
                }
            }
        }
        private Common.Models.Resource.Resource GetDomainResourceFor(Resource resource)
        {
            string schemaProperCaseNameOrDefault =
                ExtensionsConventions.GetProperCaseNameForLogicalName(resource.logicalSchema ?? EdFiConventions.ProperCaseName);

            bool IsSchemaMatch(ResourceClassBase r) => r.SchemaProperCaseName.EqualsIgnoreCase(schemaProperCaseNameOrDefault);
            bool IsNameMatch(ResourceClassBase r) => r.Name.EqualsIgnoreCase(resource.name);
            bool IsFullNameMatch(ResourceClassBase r) => IsSchemaMatch(r) && IsNameMatch(r);

            return(ResourceModel.GetAllResources()
                   .FirstOrDefault(IsFullNameMatch));
        }
        public void ValidateObjects(Profile profile, Resource resource)
        {
            var domainResource = GetDomainResourceFor(resource);

            if (domainResource == null)
            {
                throw new InvalidResourceException(resource, profile);
            }

            foreach (var objectElement in GetValidationElements(profile, resource, "Object"))
            {
                var objectName = GetValidationElementName(objectElement);

                if (!domainResource.EmbeddedObjects.Select(embeddedObj => embeddedObj.ObjectType.Name)
                    .Concat(domainResource.Extensions.Select(e => e.ObjectType.Name))
                    .Contains(objectName))
                {
                    throw new MissingForeignKeyException("Object", objectName, profile, domainResource.Name);
                }
            }
        }
 public InvalidResourceException(Resource resource, Profile profile)
     : base(string.Format(ExceptionMessage, resource.logicalSchema, resource.name, profile.name), profile)
 {
 }
 private IEnumerable <XElement> GetValidationElements(Profile profile, Resource resource, string memberType)
 => GetXElementsFromXPath(CreateMemberXPath(profile.name, resource.name, memberType));
 private string GetContainingTable(XElement validationElement, Resource resource)
 => validationElement.Parent.AttributeValue("name") ?? resource.name;