private static void FactTypeConstraintPatternChangedDelayed(ModelElement element) { FactType factType; ORMModel model; if (!element.IsDeleted && null != (model = (factType = (FactType)element).Model) && !ORMElementGateway.IsElementExcluded(factType)) { // If we're not previously mapped, then we will have been added at this point FactTypeMapsTowardsRole mapToRole = FactTypeMapsTowardsRole.GetLinkToTowardsRole(factType); if (mapToRole != null) { MappingMandatoryPattern startMandatoryPattern = mapToRole.MandatoryPattern; if (mapToRole.SynchronizeMappingPatterns()) { MappingMandatoryPattern endMandatoryPattern = mapToRole.MandatoryPattern; if (endMandatoryPattern != startMandatoryPattern) { foreach (ConceptTypeChild child in ConceptTypeChildHasPathFactType.GetConceptTypeChild(factType)) { ValidateMandatory(child, startMandatoryPattern, endMandatoryPattern); } } } else { AddTransactedModelElement(factType, ModelElementModification.ORMElementChanged); FrameworkDomainModel.DelayValidateElement(model, DelayValidateModel); } } } }
/// <summary> /// The <see cref="ConceptTypeChild.IsMandatory">IsMandatory</see> setting may /// have change, revalidate if necessary. /// </summary> /// <param name="child">The <see cref="ConceptTypeChild"/> element to validate</param> /// <param name="oldMandatory">The old mandatory pattern for any <see cref="FactType"/> in the path.</param> /// <param name="newMandatory">The new mandatory pattern for any <see cref="FactType"/> in the path.</param> private static void ValidateMandatory(ConceptTypeChild child, MappingMandatoryPattern oldMandatory, MappingMandatoryPattern newMandatory) { // We pre filter this and don't both to notify unless a change is possible bool mightHaveChanged = false; if (child.IsMandatory) { switch (oldMandatory) { case MappingMandatoryPattern.BothRolesMandatory: case MappingMandatoryPattern.TowardsRoleMandatory: switch (newMandatory) { case MappingMandatoryPattern.OppositeRoleMandatory: case MappingMandatoryPattern.NotMandatory: mightHaveChanged = true; break; } break; } } else { switch (oldMandatory) { case MappingMandatoryPattern.NotMandatory: case MappingMandatoryPattern.OppositeRoleMandatory: switch (newMandatory) { case MappingMandatoryPattern.BothRolesMandatory: case MappingMandatoryPattern.TowardsRoleMandatory: mightHaveChanged = true; break; } break; } } if (mightHaveChanged) { FrameworkDomainModel.DelayValidateElement(child, ValidateMandatoryDelayed); } }
/// <summary> /// Update the <see cref="MandatoryPattern"/> and <see cref="UniquenessPattern"/> if the current constraints /// on the associated <see cref="FactType"/> cannot change the <see cref="Depth"/> or direction of the mapping. /// If the current mapping can be influenced, then do nothing and return <see langword="false"/> /// </summary> /// <returns><see langword="true"/> if the current set of constraints on the FactType cannot change the current mapping depth or direction.</returns> public bool SynchronizeMappingPatterns() { bool retVal = false; MappingUniquenessPattern newUniquenessPattern; MappingMandatoryPattern newMandatoryPattern; GetMappingPatterns(TowardsRole, out newUniquenessPattern, out newMandatoryPattern); MappingUniquenessPattern oldUniquenessPattern = UniquenessPattern; if (newUniquenessPattern == oldUniquenessPattern) { MappingMandatoryPattern oldMandatoryPattern = MandatoryPattern; if (newMandatoryPattern == oldMandatoryPattern) { retVal = true; } else { switch (oldUniquenessPattern) { case MappingUniquenessPattern.OneToMany: // Mandatory constraints to not affect one-to-many mapping retVal = true; break; case MappingUniquenessPattern.OneToOne: // UNDONE: The answers here assume that a reduced set of // choices will result in the same answer. This is a conjecture // at this point that is likely to be true, but we're not sure. switch (oldMandatoryPattern) { case MappingMandatoryPattern.BothRolesMandatory: switch (newMandatoryPattern) { case MappingMandatoryPattern.TowardsRoleMandatory: case MappingMandatoryPattern.NotMandatory: retVal = Depth == MappingDepth.Shallow; break; case MappingMandatoryPattern.OppositeRoleMandatory: retVal = true; break; } break; case MappingMandatoryPattern.OppositeRoleMandatory: case MappingMandatoryPattern.TowardsRoleMandatory: retVal = newMandatoryPattern == MappingMandatoryPattern.NotMandatory && Depth == MappingDepth.Shallow; break; } break; } if (retVal) { MandatoryPattern = newMandatoryPattern; } } } else if (oldUniquenessPattern == MappingUniquenessPattern.OneToOne && newUniquenessPattern == MappingUniquenessPattern.OneToMany && Depth == MappingDepth.Shallow) { // Shallow towards current TowardsRole is the only remaining possibility, nothing will change retVal = true; MandatoryPattern = newMandatoryPattern; UniquenessPattern = newUniquenessPattern; } return(retVal); }
private static void GetMappingPatterns(Role towardsRole, Role fromRole, out MappingUniquenessPattern uniquenessPattern, out MappingMandatoryPattern mandatoryPattern) { if (towardsRole.FactType is SubtypeFact) { uniquenessPattern = MappingUniquenessPattern.Subtype; mandatoryPattern = (towardsRole is SubtypeMetaRole) ? MappingMandatoryPattern.TowardsRoleMandatory : MappingMandatoryPattern.OppositeRoleMandatory; } else { bool towardsRoleUnique; bool towardsRoleMandatory; bool towardsRoleImpliedMandatory; bool fromRoleUnique; bool fromRoleMandatory; bool fromRoleImpliedMandatory; bool oneToOne = false; GetUniqueAndMandatory(towardsRole, out towardsRoleUnique, out towardsRoleMandatory, out towardsRoleImpliedMandatory); GetUniqueAndMandatory(fromRole, out fromRoleUnique, out fromRoleMandatory, out fromRoleImpliedMandatory); uniquenessPattern = towardsRoleUnique ? ((oneToOne = fromRoleUnique) ? MappingUniquenessPattern.OneToOne : MappingUniquenessPattern.OneToMany) : MappingUniquenessPattern.ManyToOne; if (oneToOne && (fromRoleImpliedMandatory ^ towardsRoleImpliedMandatory)) { // Adjust mandatory patterns to ignore implied mandatory on naturally asymmetric // one-to-one relationships. if (fromRoleImpliedMandatory) { fromRoleMandatory = !towardsRoleMandatory; } else { towardsRoleMandatory = !fromRoleMandatory; } } mandatoryPattern = towardsRoleMandatory ? (fromRoleMandatory ? MappingMandatoryPattern.BothRolesMandatory : MappingMandatoryPattern.TowardsRoleMandatory) : (fromRoleMandatory ? MappingMandatoryPattern.OppositeRoleMandatory : MappingMandatoryPattern.NotMandatory); } }
private static void GetMappingPatterns(RoleBase towardsRole, out MappingUniquenessPattern uniquenessPattern, out MappingMandatoryPattern mandatoryPattern) { Role role = towardsRole.Role; GetMappingPatterns(role, role.OppositeRoleAlwaysResolveProxy.Role, out uniquenessPattern, out mandatoryPattern); }