/// <summary>
        /// Display a formatted string defining the relationship
        /// for the component name.
        /// </summary>
        public override string GetComponentName()
        {
            SubtypeFact subtypeFact = ModelElement;
            ObjectType  subtype;
            ObjectType  supertype;

            if ((subtype = subtypeFact.Subtype) != null && (supertype = subtypeFact.Supertype) != null)
            {
                return(string.Format(CultureInfo.InvariantCulture, ResourceStrings.SubtypeFactComponentNameFormat, TypeDescriptor.GetComponentName(subtype), TypeDescriptor.GetComponentName(supertype)));
            }
            return(base.GetComponentName());
        }
Example #2
0
            /// <summary>
            /// Create a connection between an ExternalConstraintShape and a FactType. Roles
            /// used in the connection are stored with the currently active connect action.
            /// </summary>
            /// <param name="sourceShapeElement">The source of the requested connection</param>
            /// <param name="targetShapeElement">The target of the requested connection</param>
            /// <param name="paintFeedbackArgs">PaintFeedbackArgs</param>
            public override void CreateConnection(ShapeElement sourceShapeElement, ShapeElement targetShapeElement, PaintFeedbackArgs paintFeedbackArgs)
            {
                SubtypeConnectAction action = (sourceShapeElement.Diagram as ORMDiagram).SubtypeConnectAction;
                ObjectType           sourceObjectType;
                ObjectType           targetObjectType;

                if ((null != (sourceObjectType = action.mySourceObjectType)) &&
                    (null != (targetObjectType = ObjectTypeFromShape(targetShapeElement))))
                {
                    SubtypeFact.Create(sourceObjectType, targetObjectType);
                }
            }
Example #3
0
        /// <summary>
        /// Implements <see cref="IReconfigureableLink.Reconfigure"/>
        /// </summary>
        protected void Reconfigure(ShapeElement discludedShape)
        {
            SubtypeFact subtypeFact = AssociatedSubtypeFact;
            ObjectType  subType     = subtypeFact.Subtype;
            ObjectType  superType   = subtypeFact.Supertype;

            if (subType != null && superType != null)
            {
                FactType nestedSubFact   = subType.NestedFactType;
                FactType nestedSuperFact = superType.NestedFactType;

                MultiShapeUtility.ReconfigureLink(this, (nestedSubFact == null) ? subType as ModelElement : nestedSubFact as ModelElement,
                                                  (nestedSuperFact == null) ? superType as ModelElement : nestedSuperFact as ModelElement, discludedShape);
            }
        }
Example #4
0
        public void Test5(Store store)
        {
            myTestServices.Compare(store, (MethodInfo)MethodInfo.GetCurrentMethod(), "FullyAbsorbed");

            myTestServices.LogMessage("Separate a one-to-main objectification");
            ORMModel   model              = store.ElementDirectory.FindElements <ORMModel>()[0];
            ObjectType birthObjectType    = (ObjectType)model.ObjectTypesDictionary.GetElement("Birth").FirstElement;
            FactType   factTypeToSeparate = birthObjectType.PreferredIdentifier.RoleCollection[0].Proxy.FactType;
            MappingCustomizationModel customizationModel;

            using (Transaction t = store.TransactionManager.BeginTransaction("Separate assimilated objectification"))
            {
                customizationModel = new MappingCustomizationModel(store);
                AssimilationMapping mapping = new AssimilationMapping(store, new PropertyAssignment(AssimilationMapping.AbsorptionChoiceDomainPropertyId, AssimilationAbsorptionChoice.Separate));
                new AssimilationMappingCustomizesFactType(mapping, factTypeToSeparate);
                mapping.Model = customizationModel;
                t.Commit();
            }
            myTestServices.Compare(store, (MethodInfo)MethodInfo.GetCurrentMethod(), "SeparateObjectification");

            myTestServices.LogMessage("Add a longer assimilation chain with a separate end point");
            ObjectType          partyObjectType = (ObjectType)model.ObjectTypesDictionary.GetElement("Party").FirstElement;
            AssimilationMapping partyIsThingAssimilationMapping;

            using (Transaction t = store.TransactionManager.BeginTransaction("Longer assimilation chain"))
            {
                partyObjectType.ReferenceModeDisplay = "";                 // Using ReferenceModeDisplay instead of ReferenceModeString to automatically kill Party_id
                ObjectType thingObjectType = new ObjectType(store, new PropertyAssignment(ObjectType.NameDomainPropertyId, "Thing"), new PropertyAssignment(ObjectType.IsIndependentDomainPropertyId, true));
                thingObjectType.Model = model;
                thingObjectType.ReferenceModeString = "id";
                SubtypeFact partyIsThingSubtypeFact = SubtypeFact.Create(partyObjectType, thingObjectType);
                partyIsThingAssimilationMapping = new AssimilationMapping(store, new PropertyAssignment(AssimilationMapping.AbsorptionChoiceDomainPropertyId, AssimilationAbsorptionChoice.Separate));
                new AssimilationMappingCustomizesFactType(partyIsThingAssimilationMapping, partyIsThingSubtypeFact);
                partyIsThingAssimilationMapping.Model = customizationModel;
                t.Commit();
            }

            myTestServices.Compare(store, (MethodInfo)MethodInfo.GetCurrentMethod(), "SeparateRemoteSupertype");

            myTestServices.LogMessage("Remove the remote separation");
            using (Transaction t = store.TransactionManager.BeginTransaction(""))
            {
                partyIsThingAssimilationMapping.AbsorptionChoice = AssimilationAbsorptionChoice.Absorb;
                t.Commit();
            }
        }
 /// <summary>
 /// Ensure that the <see cref="SubtypeFact.ProvidesPreferredIdentifier"/> property is read-only when
 /// it is <see langword="true"/>.
 /// </summary>
 protected override bool IsPropertyDescriptorReadOnly(ElementPropertyDescriptor propertyDescriptor)
 {
     if (propertyDescriptor.DomainPropertyInfo.Id.Equals(SubtypeFact.ProvidesPreferredIdentifierDomainPropertyId))
     {
         SubtypeFact subtypeFact = ModelElement;
         ObjectType  subtype     = subtypeFact.Subtype;
         if (subtypeFact.ProvidesPreferredIdentifier)
         {
             // We can only turn this off if there is a single candidate
             // internal uniqueness constraint on an objectification that
             // can automatically take the preferred identifier
             FactType objectifiedFactType;
             if (null != (objectifiedFactType = subtype.NestedFactType))
             {
                 if (objectifiedFactType.UnaryRole != null)
                 {
                     // The uniqueness constraint on the objectified unary
                     // role is the only possible candidate
                     return(false);
                 }
                 else
                 {
                     int pidCandidateCount = 0;
                     foreach (UniquenessConstraint uc in objectifiedFactType.GetInternalConstraints <UniquenessConstraint>())
                     {
                         if (++pidCandidateCount > 1)
                         {
                             break;
                         }
                     }
                     if (pidCandidateCount == 1)
                     {
                         return(false);
                     }
                 }
             }
             return(true);
         }
         UniquenessConstraint pid;
         return(null != (subtype = subtypeFact.Subtype) && null != (pid = subtype.PreferredIdentifier) && !pid.IsObjectifiedPreferredIdentifier);
     }
     return(base.IsPropertyDescriptorReadOnly(propertyDescriptor));
 }
Example #6
0
            /// <summary>
            /// Add subtype links when possible
            /// </summary>
            /// <param name="element">An ModelHasFactType instance</param>
            /// <param name="store">The context store</param>
            /// <param name="notifyAdded">The listener to notify if elements are added during fixup</param>
            protected sealed override void ProcessElement(ModelHasFactType element, Store store, INotifyElementAdded notifyAdded)
            {
                SubtypeFact subTypeFact = element.FactType as SubtypeFact;
                ORMModel    model;

                if (null != (subTypeFact = element.FactType as SubtypeFact) &&
                    !subTypeFact.IsDeleted &&
                    null != (model = subTypeFact.Model))
                {
                    ObjectType rolePlayer = subTypeFact.Subtype;
                    FactType   nestedFact = rolePlayer.NestedFactType;
                    if (FactTypeShape.ShouldDrawObjectification(nestedFact))
                    {
                        Diagram.FixUpDiagram(model, nestedFact);
                        Diagram.FixUpDiagram(nestedFact, rolePlayer);
                    }
                    else
                    {
                        Diagram.FixUpDiagram(model, rolePlayer);
                    }
                    rolePlayer = subTypeFact.Supertype;
                    nestedFact = rolePlayer.NestedFactType;
                    if (FactTypeShape.ShouldDrawObjectification(nestedFact))
                    {
                        Diagram.FixUpDiagram(model, nestedFact);
                        Diagram.FixUpDiagram(nestedFact, rolePlayer);
                    }
                    else
                    {
                        Diagram.FixUpDiagram(model, rolePlayer);
                    }

                    object AllowMultipleShapes;
                    Dictionary <object, object> topLevelContextInfo;
                    bool containedAllowMultipleShapes;
                    if (!(containedAllowMultipleShapes = (topLevelContextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo).ContainsKey(AllowMultipleShapes = MultiShapeUtility.AllowMultipleShapes)))
                    {
                        topLevelContextInfo.Add(AllowMultipleShapes, null);
                    }

                    foreach (PresentationViewsSubject presentationViewsSubject in DomainRoleInfo.GetElementLinks <PresentationViewsSubject>(model, PresentationViewsSubject.SubjectDomainRoleId))
                    {
                        ORMDiagram diagram;
                        if ((diagram = presentationViewsSubject.Presentation as ORMDiagram) != null)
                        {
                            ObjectType subtype = subTypeFact.Subtype;
                            // add a link shape for each object type shape on the diagram for the played role
                            foreach (ObjectTypeShape shapeElement in MultiShapeUtility.FindAllShapesForElement <ObjectTypeShape>(diagram, subtype))
                            {
                                diagram.FixUpLocalDiagram(subTypeFact);
                            }
                            FactType objectifiedFactType;
                            if (null != (objectifiedFactType = subtype.NestedFactType))
                            {
                                foreach (FactTypeShape shapeElement in MultiShapeUtility.FindAllShapesForElement <FactTypeShape>(diagram, objectifiedFactType))
                                {
                                    diagram.FixUpLocalDiagram(subTypeFact);
                                }
                            }
                        }
                    }

                    if (!containedAllowMultipleShapes)
                    {
                        topLevelContextInfo.Remove(AllowMultipleShapes);
                    }
                }
            }
        public void ResolvePreferredTest1(Store store)
        {
            IElementDirectory   directory       = store.ElementDirectory;
            SubtypeFact         FiveToTwo       = (SubtypeFact)directory.GetElement(new Guid("9B85CC3F-FAA1-485B-A6CA-DE65165C6AE5"));
            SubtypeFact         FiveToThree     = (SubtypeFact)directory.GetElement(new Guid("C48F356A-DC20-4CD8-AD6A-EE4518622FFB"));
            SubtypeFact         SixToFive       = (SubtypeFact)directory.GetElement(new Guid("321CD412-8DAA-4D35-8D4E-D8D5915F07E0"));
            SubtypeFact         SixToSeven      = (SubtypeFact)directory.GetElement(new Guid("D6A4C2F2-3F99-4E2F-AB2F-407E03AB6F42"));
            SubtypeFact         FiveToFour      = (SubtypeFact)directory.GetElement(new Guid("DE1FC770-19A5-4CA9-AEF7-CE1204D80270"));
            SubtypeFact         SevenToFour     = (SubtypeFact)directory.GetElement(new Guid("71D29425-481E-445B-8F8A-63E9F29F761A"));
            ORMModel            model           = FiveToTwo.Model;
            RoleValueConstraint valueConstraint = (RoleValueConstraint)model.ConstraintsDictionary.GetElement("RoleValueConstraint1").SingleElement;

            myTestServices.LogValidationErrors("Expected three initial errors");

            myTestServices.LogMessage("Scenario 1: Make 5->2 preferred path, sibling and downstream subtypes should all be preferred");
            DomainTypeDescriptor.CreatePropertyDescriptor(FiveToTwo, SubtypeFact.ProvidesPreferredIdentifierDomainPropertyId).SetValue(FiveToTwo, true);
            myTestServices.LogValidationErrors("No errors expected");
            myTestServices.LogMessage("5->4, 6->5, 6->7 are on the preferred path: " + (FiveToFour.ProvidesPreferredIdentifier && SixToFive.ProvidesPreferredIdentifier && SixToSeven.ProvidesPreferredIdentifier).ToString());
            myTestServices.LogMessage("ValueConstraint should be a string type: " + valueConstraint.Text);

            myTestServices.LogMessage("Scenario 2: Make 5->3 preferred path, downstream subtypes are no ambiguous");
            DomainTypeDescriptor.CreatePropertyDescriptor(FiveToThree, SubtypeFact.ProvidesPreferredIdentifierDomainPropertyId).SetValue(FiveToThree, true);
            myTestServices.LogValidationErrors("Two errors expected");
            myTestServices.LogMessage("5->2, 5->4, 6->5, 6->7 are not preferred: " + (!(FiveToTwo.ProvidesPreferredIdentifier || FiveToFour.ProvidesPreferredIdentifier || SixToFive.ProvidesPreferredIdentifier || SixToSeven.ProvidesPreferredIdentifier)).ToString());

            myTestServices.LogMessage("Scenario 3: Make 6->5 preferred path");
            DomainTypeDescriptor.CreatePropertyDescriptor(SixToFive, SubtypeFact.ProvidesPreferredIdentifierDomainPropertyId).SetValue(SixToFive, true);
            myTestServices.LogValidationErrors("No errors expected");
            myTestServices.LogMessage("6->7 is not on the preferred path: " + (!SixToSeven.ProvidesPreferredIdentifier).ToString());
            myTestServices.LogMessage("ValueConstraint should be a number type: " + valueConstraint.Text);

            myTestServices.LogMessage("Scenario 4: Make 6->7 preferred path");
            DomainTypeDescriptor.CreatePropertyDescriptor(SixToSeven, SubtypeFact.ProvidesPreferredIdentifierDomainPropertyId).SetValue(SixToSeven, true);
            myTestServices.LogValidationErrors("No errors expected");
            myTestServices.LogMessage("6->5 is not on the preferred path: " + (!SixToFive.ProvidesPreferredIdentifier).ToString());
            myTestServices.LogMessage("ValueConstraint should be a string type: " + valueConstraint.Text);

            myTestServices.LogMessage("Scenario 5: Delete 7->4 to break subtype structure");
            using (Transaction t = store.TransactionManager.BeginTransaction("Break graph"))
            {
                SevenToFour.Delete();
                t.Commit();
            }
            myTestServices.LogValidationErrors("Expecting invalid graph, detached valuetype, and no reference scheme errors");

            myTestServices.LogMessage("Scenario 6: Delete 6->5 to make graph valid");
            using (Transaction t = store.TransactionManager.BeginTransaction("Graph OK"))
            {
                SixToFive.Delete();
                t.Commit();
            }
            myTestServices.LogValidationErrors("Expecting detached valuetype and no reference scheme errors");

            myTestServices.LogMessage("Scenario 7: Set identifier on 7 to clear errors");
            using (Transaction t = store.TransactionManager.BeginTransaction("Clear errors"))
            {
                SixToSeven.Supertype.ReferenceModeString = "id";
                t.Commit();
            }
            myTestServices.LogValidationErrors("No errors expected");

            myTestServices.LogValidationErrors("Scenario 8: (Undo scenarios 5-7) Make 5->4 preferred path and give 4 an explicit id in one transaction");
            store.UndoManager.Undo();
            store.UndoManager.Undo();
            store.UndoManager.Undo();
            using (Transaction t = store.TransactionManager.BeginTransaction("Change id and make preferred in one transaction"))
            {
                // Note that doing this in the opposite order in two transactions has the same result
                FiveToFour.ProvidesPreferredIdentifier   = true;
                FiveToFour.Supertype.ReferenceModeString = "id";
                t.Commit();
            }
            myTestServices.LogValidationErrors("No errors expected");

            myTestServices.LogValidationErrors("Scenario 9: (Undo scenario 8) Make 5->4 preferred path then give 4 an explicit id to make 5 and 6 ambiguous");
            store.UndoManager.Undo();
            using (Transaction t = store.TransactionManager.BeginTransaction("Change preferred path"))
            {
                FiveToFour.ProvidesPreferredIdentifier = true;
                t.Commit();
            }
            using (Transaction t = store.TransactionManager.BeginTransaction("Introduce id that interferes with split identifier path"))
            {
                FiveToFour.Supertype.ReferenceModeString = "id";
                t.Commit();
            }
        }