/// <summary> /// Initial the role pattern and constraints for a standard /// subtype. This should be called after the subtype is parented /// by either the model or an alternate owner so that the created /// elements can also be properly parented. /// </summary> protected void InitializeIdentityFactType() { Store store; if (CopyMergeUtility.GetIntegrationPhase(store = this.Store) == CopyClosureIntegrationPhase.None) { IDictionary <object, object> contextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo; try { // Establish role collecton contextInfo[InitializingIdentityFactTypeKey] = null; LinkedElementCollection <RoleBase> roles = this.RoleCollection; Partition partition = this.Partition; SubtypeMetaRole subTypeMetaRole = new SubtypeMetaRole(partition); SupertypeMetaRole superTypeMetaRole = new SupertypeMetaRole(partition); roles.Add(subTypeMetaRole); roles.Add(superTypeMetaRole); // Add injection constraints superTypeMetaRole.Multiplicity = RoleMultiplicity.ExactlyOne; subTypeMetaRole.Multiplicity = RoleMultiplicity.ZeroToOne; } finally { contextInfo.Remove(InitializingIdentityFactTypeKey); } } }
/// <summary> /// AddRule: typeof(NameAlias), FireTime=LocalCommit, Priority=FrameworkDomainModel.CopyClosureExpansionCompletedRulePriority; /// </summary> private static void AliasAddedClosureRule(ElementAddedEventArgs e) { ModelElement element = e.ModelElement; if (!element.IsDeleted && CopyMergeUtility.GetIntegrationPhase(element.Store) == CopyClosureIntegrationPhase.IntegrationComplete) { ((NameAlias)element).DeleteIfTypeBindingFailed(); } }
/// <summary> /// AddRule: typeof(FactTypeHasRole) /// Rule to detect when a Role is added to the FactType so that it /// can also be added to the ReadingOrders and their Readings. /// </summary> private static void FactTypeHasRoleAddedRule(ElementAddedEventArgs e) { FactTypeHasRole link = (FactTypeHasRole)e.ModelElement; if (CopyMergeUtility.GetIntegrationPhase(link.Store) != CopyClosureIntegrationPhase.Integrating) { // UNDONE: COPYMERGE Do we need to run a similar rule on integration complete // to handle merge cases where roles are added to a model with additional // readings on the merged fact type. ValidateReadingOrdersRoleCollection(link.FactType, link.Role); } }
/// <summary> /// AddRule: typeof(FactSetConstraint) /// Block internal constraints from being added to a subtype /// after it is included in a model. /// </summary> private static void LimitSubtypeConstraintsAddRule(ElementAddedEventArgs e) { FactSetConstraint link = (FactSetConstraint)e.ModelElement; SubtypeFact subtypeFact; Store store; if (link.SetConstraint.Constraint.ConstraintIsInternal && null != (subtypeFact = link.FactType as SubtypeFact) && subtypeFact.ResolvedModel != null && CopyMergeUtility.GetIntegrationPhase(store = link.Store) == CopyClosureIntegrationPhase.None) { // Allow before adding to model, not afterwards, // unless there is an active copy operation. ThrowPatternModifiedException(store); } }
/// <summary> /// AddRule: typeof(FactTypeHasRole) /// Block roles from being added to a subtype /// after it is included in a model. /// </summary> private static void LimitSubtypeRolesAddRule(ElementAddedEventArgs e) { FactTypeHasRole link = (FactTypeHasRole)e.ModelElement; SubtypeFact subtypeFact; if (null != (subtypeFact = link.FactType as SubtypeFact)) { Store store; if (subtypeFact.ResolvedModel != null && CopyMergeUtility.GetIntegrationPhase(store = link.Store) == CopyClosureIntegrationPhase.None) { // Allow before adding to model, not afterwards ThrowPatternModifiedException(store); } } else { RoleBase role = link.Role; if (role is SubtypeMetaRole || role is SupertypeMetaRole) { throw new InvalidOperationException(ResourceStrings.ModelExceptionSubtypeFactMustBeParentOfMetaRole); } } }
/// <summary> /// AddRule: typeof(ConstraintRoleSequenceHasRole) /// Block internal constraints from being modified on a subtype, block /// external constraints from being added to the subtype role, and /// limit external constraints being added to the supertype role /// </summary> private static void LimitSubtypeConstraintRolesAddRule(ElementAddedEventArgs e) { ConstraintRoleSequenceHasRole link = e.ModelElement as ConstraintRoleSequenceHasRole; Role untypedRole = link.Role; SupertypeMetaRole supertypeRole = untypedRole as SupertypeMetaRole; SubtypeMetaRole subtypeRole = (supertypeRole == null) ? untypedRole as SubtypeMetaRole : null; ConstraintRoleSequence sequence = link.ConstraintRoleSequence; IConstraint constraint; if (supertypeRole != null || subtypeRole != null) { SetConstraint ic; SetComparisonConstraintRoleSequence externalSequence; bool invalidConstraintOnSubtypeRole = false; bool invalidConstraintOnSupertypeRole = false; if (null != (ic = sequence as SetConstraint)) { constraint = ic.Constraint; if (constraint.ConstraintIsInternal) { SubtypeFact subtypeFact; Store store; if (null != (subtypeFact = untypedRole.FactType as SubtypeFact) && subtypeFact.ResolvedModel != null && CopyMergeUtility.GetIntegrationPhase(store = subtypeFact.Store) == CopyClosureIntegrationPhase.None) { // Allow before adding to model, not afterwards ThrowPatternModifiedException(store); } } else if (constraint.ConstraintType == ConstraintType.ImpliedMandatory) { // Nothing to do } else if (subtypeRole != null) { invalidConstraintOnSubtypeRole = true; } else if (constraint.ConstraintType != ConstraintType.DisjunctiveMandatory) { invalidConstraintOnSupertypeRole = true; } } else if (subtypeRole != null) { invalidConstraintOnSubtypeRole = true; } else if (null != (externalSequence = sequence as SetComparisonConstraintRoleSequence)) { constraint = externalSequence.Constraint; if (constraint != null) { switch (constraint.ConstraintType) { case ConstraintType.Exclusion: FrameworkDomainModel.DelayValidateElement((ModelElement)constraint, DelayValidateSupertypeExclusionSingleColumnOnly); break; case ConstraintType.Subset: FrameworkDomainModel.DelayValidateElement((ModelElement)constraint, DelayValidateSupertypeSubsetPattern); break; default: invalidConstraintOnSupertypeRole = true; break; } } } if (invalidConstraintOnSupertypeRole) { ThrowInvalidSupertypeMetaRoleConstraint(); } else if (invalidConstraintOnSubtypeRole) { ThrowInvalidSubtypeMetaRoleConstraint(); } } else if (null != (constraint = sequence.Constraint)) { switch (constraint.ConstraintType) { case ConstraintType.Exclusion: FrameworkDomainModel.DelayValidateElement((ModelElement)constraint, DelayValidateSupertypeExclusionSingleColumnOnly); break; case ConstraintType.Subset: FrameworkDomainModel.DelayValidateElement((ModelElement)constraint, DelayValidateSupertypeSubsetPattern); break; } } }