/// <summary>See <see cref="ORMShapeToolboxHelperBase.CreateElementToolPrototype"/>.</summary>
        protected sealed override ElementGroupPrototype CreateElementToolPrototype(Store store, Guid domainClassId)
        {
            // WARNING: This method is _extremely_ order-sensitive. If the order that the toolbox items are listed
            // in the .dsl file changes, or if the DSL Tools text template that is used to generate ORMShapeModelToolboxHelperBase
            // changes, this method will most likely need to be changed as well.

            ElementGroup group       = null;
            bool         unknownItem = false;

            if (domainClassId.Equals(ObjectType.DomainClassId))
            {
                group = new ElementGroup(store);
                ObjectType objectType = new ObjectType(store);
                group.AddGraph(objectType, true);
                switch (myObjectTypeCount++)
                {
                case 0:
                    // EntityType - We don't need to do anything else...
                    break;

                case 1:
                    // ValueType
                    // Do not try to set the IsValueType property here. IsValueType picks
                    // up the default data type for the model, which can only be done
                    // when the model is known. Instead, flag the element so that it
                    // can be set during MergeRelate on the model.
                    group.UserData = ORMModel.ValueTypeUserDataKey;
                    break;

                case 2:
                    // ObjectifiedFactType
                    group.AddGraph(new Objectification(objectType, AddFactType(store, group, 2)), false);
                    break;

                default:
                    unknownItem = true;
                    break;
                }
            }
            else if (domainClassId.Equals(FactType.DomainClassId))
            {
                group = new ElementGroup(store);
                Debug.Assert(myFactTypeCount < 3);
                AddFactType(store, group, ++myFactTypeCount);
            }
            else if (domainClassId.Equals(ExclusiveOrConstraintCoupler.DomainClassId))
            {
                group = new ElementGroup(store);
                MandatoryConstraint mandatory = new MandatoryConstraint(store, null);
                group.AddGraph(mandatory, true);
                ExclusionConstraint exclusion = new ExclusionConstraint(store, null);
                group.AddGraph(exclusion, true);
                group.AddGraph(new ExclusiveOrConstraintCoupler(mandatory, exclusion), false);
            }
            else if (domainClassId.Equals(UniquenessConstraint.DomainClassId))
            {
                group = new ElementGroup(store);
                if (myUniquenessConstraintCount == 0)
                {
                    // Add this here so that we can distinguish between internal and external uniqueness
                    // constraints without unpacking the model. We want to merge internals into a fact
                    // and externals into the model.
                    group.UserData = ORMModel.InternalUniquenessConstraintUserDataKey;
                    group.AddGraph(UniquenessConstraint.CreateInternalUniquenessConstraint(store.DefaultPartition), true);
                }
                else
                {
                    Debug.Assert(myUniquenessConstraintCount == 1);
                    group.AddGraph(new UniquenessConstraint(store), true);
                }
                myUniquenessConstraintCount++;
            }
            return((group == null || unknownItem) ? base.CreateElementToolPrototype(store, domainClassId) : group.CreatePrototype());
        }
Beispiel #2
0
            private static void EnsureSingleColumnUniqueAndMandatory(SubtypeFact subtypeFact, Role role, bool requireMandatory, INotifyElementAdded notifyAdded)
            {
                LinkedElementCollection <ConstraintRoleSequence> sequences = role.ConstraintRoleSequenceCollection;
                int           sequenceCount  = sequences.Count;
                bool          haveUniqueness = false;
                bool          haveMandatory  = !requireMandatory;
                SetConstraint ic;

                for (int i = sequenceCount - 1; i >= 0; --i)
                {
                    ic = sequences[i] as SetConstraint;
                    if (ic != null && ic.Constraint.ConstraintIsInternal)
                    {
                        if (ic.RoleCollection.Count == 1 && ic.Modality == ConstraintModality.Alethic)
                        {
                            switch (ic.Constraint.ConstraintType)
                            {
                            case ConstraintType.InternalUniqueness:
                                if (haveUniqueness)
                                {
                                    ic.Delete();
                                }
                                else
                                {
                                    haveUniqueness = true;
                                }
                                break;

                            case ConstraintType.SimpleMandatory:
                                if (haveMandatory)
                                {
                                    ic.Delete();
                                }
                                else
                                {
                                    haveMandatory = true;
                                }
                                break;
                            }
                        }
                        else
                        {
                            ic.Delete();
                        }
                    }
                }
                if (!haveUniqueness || !haveMandatory)
                {
                    IHasAlternateOwner <FactType>          toAlternateOwner;
                    IAlternateElementOwner <SetConstraint> alternateConstraintOwner;
                    if (null != (toAlternateOwner = subtypeFact as IHasAlternateOwner <FactType>) &&
                        null != (alternateConstraintOwner = toAlternateOwner.AlternateOwner as IAlternateElementOwner <SetConstraint>))
                    {
                        if (!haveUniqueness)
                        {
                            ic = UniquenessConstraint.CreateInternalUniquenessConstraint(subtypeFact);
                            ic.RoleCollection.Add(role);
                            notifyAdded.ElementAdded(ic, true);
                        }
                    }
                    if (!haveMandatory)
                    {
                        ic = MandatoryConstraint.CreateSimpleMandatoryConstraint(role);
                        notifyAdded.ElementAdded(ic, true);
                    }
                }
            }
            /// <summary>
            /// Binarizes the unary <see cref="FactType"/> specified by <paramref name="unaryFactType"/>, defaulting
            /// to using open-world assumption. The caller is responsible for making sure <paramref name="unaryFactType"/>
            /// is in fact a unary fact type.
            /// </summary>
            public static void BinarizeUnary(FactType unaryFactType, INotifyElementAdded notifyAdded)
            {
                Partition partition = unaryFactType.Partition;
                Store     store     = partition.Store;
                IHasAlternateOwner <FactType>      toAlternateOwner;
                IAlternateElementOwner <FactType>  alternateFactTypeOwner = (null == (toAlternateOwner = unaryFactType as IHasAlternateOwner <FactType>)) ? null : toAlternateOwner.AlternateOwner;
                LinkedElementCollection <RoleBase> roleCollection         = unaryFactType.RoleCollection;

                Debug.Assert(roleCollection.Count == 1, "Unaries should only have one role.");

                Role   unaryRole = (Role)roleCollection[0];
                string implicitBooleanValueTypeName = GetImplicitBooleanValueTypeName(unaryRole);

                // UNDONE: We are using open-world assumption now
                // Setup the mandatory constraint (for closed-world assumption)
                //MandatoryConstraint mandatoryConstraint = MandatoryConstraint.CreateSimpleMandatoryConstraint(unaryRole);
                //mandatoryConstraint.Model = unaryFactType.Model;
                //if (notifyAdded != null)
                //{
                //    notifyAdded.ElementAdded(mandatoryConstraint, true);
                //}

                // Setup the uniqueness constraint (to make the newly binarized FactType valid)
                if (unaryRole.SingleRoleAlethicUniquenessConstraint == null)
                {
                    UniquenessConstraint uniquenessConstraint = UniquenessConstraint.CreateInternalUniquenessConstraint(unaryFactType);
                    uniquenessConstraint.RoleCollection.Add(unaryRole);
                    if (notifyAdded != null)
                    {
                        notifyAdded.ElementAdded(uniquenessConstraint, true);
                    }
                }

                // Setup the boolean role (to make the FactType a binary)
                Role implicitBooleanRole = new Role(partition, null);

                implicitBooleanRole.Name = unaryRole.Name;

                // Setup the boolean value type (because the boolean role needs a role player)

                IAlternateElementOwner <ObjectType> alternateObjectTypeOwner = null;
                DomainClassInfo alternateCtor =
                    (null != alternateFactTypeOwner &&
                     null != (alternateObjectTypeOwner = alternateFactTypeOwner as IAlternateElementOwner <ObjectType>)) ?
                    alternateObjectTypeOwner.GetOwnedElementClassInfo(typeof(ObjectType)) :
                    null;
                PropertyAssignment implicitBooleanProperty  = new PropertyAssignment(ObjectType.IsImplicitBooleanValueDomainPropertyId, true);
                ObjectType         implicitBooleanValueType = (alternateCtor != null) ?
                                                              (ObjectType)partition.ElementFactory.CreateElement(alternateCtor, implicitBooleanProperty) :
                                                              new ObjectType(partition, implicitBooleanProperty);
                Dictionary <object, object> contextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo;
                object duplicateNamesKey         = ORMModel.AllowDuplicateNamesKey;
                bool   removeDuplicateNamesKey   = false;
                object duplicateSignaturesKey    = ORMModel.BlockDuplicateReadingSignaturesKey;
                bool   addDuplicateSignaturesKey = false;

                try
                {
                    if (!contextInfo.ContainsKey(duplicateNamesKey))
                    {
                        contextInfo[duplicateNamesKey] = null;
                        removeDuplicateNamesKey        = true;
                    }
                    if (contextInfo.ContainsKey(duplicateSignaturesKey))
                    {
                        contextInfo[duplicateSignaturesKey] = null;
                        addDuplicateSignaturesKey           = true;
                    }
                    implicitBooleanValueType.Name = implicitBooleanValueTypeName;
                    if (alternateCtor != null)
                    {
                        ((IHasAlternateOwner <ObjectType>)implicitBooleanValueType).AlternateOwner = alternateObjectTypeOwner;
                    }
                    else
                    {
                        implicitBooleanValueType.Model = unaryFactType.ResolvedModel;
                    }
                    if (notifyAdded != null)
                    {
                        notifyAdded.ElementAdded(implicitBooleanValueType, true);
                    }
                }
                finally
                {
                    if (removeDuplicateNamesKey)
                    {
                        contextInfo.Remove(duplicateNamesKey);
                    }
                    if (addDuplicateSignaturesKey)
                    {
                        contextInfo[duplicateSignaturesKey] = null;
                    }
                }
                implicitBooleanValueType.DataType = store.ElementDirectory.FindElements <TrueOrFalseLogicalDataType>(false)[0];

                // Set value constraint on implicit boolean ValueType for open-world assumption
                ValueTypeValueConstraint implicitBooleanValueConstraint = implicitBooleanValueType.ValueConstraint
                                                                              = new ValueTypeValueConstraint(partition, null);

                // Add the true-only ValueRange to the value constraint for open-world assumption
                implicitBooleanValueConstraint.ValueRangeCollection.Add(new ValueRange(partition,
                                                                                       new PropertyAssignment(ValueRange.MinValueDomainPropertyId, bool.TrueString),
                                                                                       new PropertyAssignment(ValueRange.MaxValueDomainPropertyId, bool.TrueString)));

                // Make the boolean value type the role player for the implicit boolean role
                implicitBooleanRole.RolePlayer = implicitBooleanValueType;

                // Add the boolean role to the FactType
                roleCollection.Add(implicitBooleanRole);
                if (notifyAdded != null)
                {
                    notifyAdded.ElementAdded(implicitBooleanRole, true);
                }
            }