/// <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(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; } } }