/// <summary>
        /// DeletingRule: typeof(ReadingOrderHasRole)
        /// Handles the clean up of the readings that the role is involved in by replacing
        /// the place holder with the text DELETED
        /// </summary>
        private static void ReadingOrderHasRoleDeletingRule(ElementDeletingEventArgs e)
        {
            ReadingOrderHasRole link             = e.ModelElement as ReadingOrderHasRole;
            RoleBase            linkRole         = link.Role;
            ReadingOrder        linkReadingOrder = link.ReadingOrder;

            if (linkReadingOrder.IsDeleting || linkReadingOrder.IsDeleted)
            {
                // Don't validate if we're removing the reading order
                return;
            }
            FactType factType = linkReadingOrder.FactType;

            if (factType != null)
            {
                FrameworkDomainModel.DelayValidateElement(factType, DelayValidateReadingOrderCollation);
            }

            int pos = linkReadingOrder.RoleCollection.IndexOf(linkRole);

            if (pos >= 0)
            {
                bool isUnaryFactType = factType.UnaryRole != null;
                LinkedElementCollection <Reading> readings = linkReadingOrder.ReadingCollection;
                int numReadings = readings.Count;
                int roleCount   = linkReadingOrder.RoleCollection.Count;
                for (int iReading = 0; iReading < numReadings; ++iReading)
                {
                    Reading linkReading = readings[iReading];
                    if (!linkReading.IsDeleting)
                    {
                        Debug.Assert(!linkReading.IsDeleted);
                        string          text           = linkReading.Text;
                        IFormatProvider formatProvider = CultureInfo.InvariantCulture;
                        linkReading.SetAutoText(Reading.ReplaceFields(
                                                    linkReading.Text,
                                                    delegate(int replaceIndex)
                        {
                            if (replaceIndex == pos)
                            {
                                return(isUnaryFactType ? "" : ResourceStrings.ModelReadingRoleDeletedRoleText);
                            }
                            else if (replaceIndex > pos)
                            {
                                return("{" + (replaceIndex - 1).ToString(formatProvider) + "}");
                            }
                            return(null);
                        }
                                                    ));
                    }
                }
            }
        }
        /// <summary>
        /// RolePlayerChangeRule: typeof(ReadingOrderHasReading), FireTime=LocalCommit, Priority=ORMCoreDomainModel.BeforeDelayValidateRulePriority;
        /// </summary>
        private static void EnforceNoEmptyReadingOrderRolePlayerChangeRule(RolePlayerChangedEventArgs e)
        {
            ReadingOrderHasReading link = e.ElementLink as ReadingOrderHasReading;

            if (e.DomainRole.Id == ReadingOrderHasReading.ReadingOrderDomainRoleId)
            {
                ReadingOrder order = (ReadingOrder)e.OldRolePlayer;
                if (!order.IsDeleted && order.ReadingCollection.Count == 0)
                {
                    order.Delete();
                }
            }
        }
        /// <summary>
        /// DeleteRule: typeof(ReadingOrderHasReading), FireTime=LocalCommit, Priority=ORMCoreDomainModel.BeforeDelayValidateRulePriority;
        /// If the ReadingOrder.ReadingCollection is empty then remove the ReadingOrder
        /// </summary>
        private static void EnforceNoEmptyReadingOrderDeleteRule(ElementDeletedEventArgs e)
        {
            ReadingOrderHasReading link    = e.ModelElement as ReadingOrderHasReading;
            ReadingOrder           readOrd = link.ReadingOrder;

            if (!readOrd.IsDeleted)
            {
                if (readOrd.ReadingCollection.Count == 0)
                {
                    readOrd.Delete();
                }
            }
        }
        /// <summary>
        /// Common place for code to deal with roles that exist in a fact
        /// but do not exist in the ReadingOrder objects that it contains.
        /// This allows it to be used by both the rule and to be called
        /// during post load model fixup.
        /// </summary>
        private static void ValidateReadingOrdersRoleCollection(FactType factType, RoleBase addedRole)
        {
            LinkedElementCollection <ReadingOrder> readingOrders;
            int orderCount;

            if (null == factType.UnaryRole &&
                0 != (orderCount = (readingOrders = factType.ReadingOrderCollection).Count))
            {
                bool            checkedContext = false;
                bool            insertAfter    = false;
                RoleBase        insertBeside   = null;
                IFormatProvider formatProvider = CultureInfo.InvariantCulture;
                for (int i = 0; i < orderCount; ++i)
                {
                    ReadingOrder ord = readingOrders[i];
                    LinkedElementCollection <RoleBase> roles = ord.RoleCollection;
                    if (!roles.Contains(addedRole))
                    {
                        if (!checkedContext)
                        {
                            checkedContext = true;
                            Dictionary <object, object> contextInfo = factType.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo;
                            object contextRole;
                            if (contextInfo.TryGetValue(FactType.InsertAfterRoleKey, out contextRole))
                            {
                                insertBeside = contextRole as RoleBase;
                                insertAfter  = true;
                            }
                            else if (contextInfo.TryGetValue(FactType.InsertBeforeRoleKey, out contextRole))
                            {
                                insertBeside = contextRole as RoleBase;
                            }
                        }
                        int insertIndex = -1;
                        if (insertBeside != null)
                        {
                            insertIndex = roles.IndexOf(insertBeside);
                        }

                        if (insertIndex != -1)
                        {
                            roles.Insert(insertIndex + (insertAfter ? 1 : 0), addedRole);
                        }
                        else
                        {
                            roles.Add(addedRole);
                        }
                        LinkedElementCollection <Reading> readings = ord.ReadingCollection;
                        int readingCount = readings.Count;
                        if (readingCount != 0)
                        {
                            if (insertIndex == -1)
                            {
                                string appendText = string.Concat("  {", (roles.Count - 1).ToString(CultureInfo.InvariantCulture), "}");
                                for (int j = 0; j < readingCount; ++j)
                                {
                                    Reading reading = readings[j];
                                    reading.SetAutoText(reading.Text + appendText);
                                }
                            }
                            else
                            {
                                for (int j = 0; j < readingCount; ++j)
                                {
                                    Reading reading = readings[j];
                                    reading.SetAutoText(Reading.ReplaceFields(
                                                            reading.Text,
                                                            delegate(int replaceIndex)
                                    {
                                        // UNDONE: Respect leading/trailing hyphen binding and keep them associated
                                        // with the corresponding role. Will require work well beyond the scope of this
                                        // routine.
                                        if (replaceIndex == insertIndex)
                                        {
                                            return(string.Concat("{", insertIndex.ToString(formatProvider), "} {", (insertIndex + 1).ToString(formatProvider), "}"));
                                        }
                                        else if (replaceIndex > insertIndex)
                                        {
                                            return(string.Concat("{", (replaceIndex + 1).ToString(formatProvider), "}"));
                                        }
                                        return(null);                                                // Leave as is
                                    }
                                                            ));
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Verify that all <see cref="ReadingOrder"/>s have unique <see cref="ReadingOrder.RoleCollection">role collections</see>
        /// </summary>
        /// <param name="element">A <see cref="FactType"/></param>
        private static void DelayValidateReadingOrderCollation(ModelElement element)
        {
            if (element.IsDeleted)
            {
                return;
            }
            FactType factType = (FactType)element;
            LinkedElementCollection <ReadingOrder> ordersCollection = factType.ReadingOrderCollection;
            int orderCount = ordersCollection.Count;

            if (orderCount > 1)
            {
                // Get all orders in a collatable form, starting by caching information locally
                // so it is easily accessed. Note that this will also change the collection we're
                // iterating so we need to be careful about changes.
                ReadingOrder[] orders = new ReadingOrder[orderCount];
                ordersCollection.CopyTo(orders, 0);
                LinkedElementCollection <RoleBase>[] roleCollections = new LinkedElementCollection <RoleBase> [orderCount];
                for (int i = 0; i < orderCount; ++i)
                {
                    roleCollections[i] = orders[i].RoleCollection;
                }

                // Priority is top down, so we move later readings into a higher reading order
                for (int i = 0; i < orderCount; ++i)
                {
                    ReadingOrder currentOrder = orders[i];
                    for (int j = i + 1; j < orderCount; ++j)
                    {
                        ReadingOrder compareToOrder = orders[j];
                        if (compareToOrder != null)                         // Will be null if it has already been recognized as a duplicate
                        {
                            // These should all have the same count, but it doesn't hurt to be defensive
                            LinkedElementCollection <RoleBase> currentRoles   = roleCollections[i];
                            LinkedElementCollection <RoleBase> compareToRoles = roleCollections[j];
                            int roleCount = currentRoles.Count;
                            if (roleCount == compareToRoles.Count)
                            {
                                int k = 0;
                                for (; k < roleCount; ++k)
                                {
                                    if (currentRoles[k] != compareToRoles[k])
                                    {
                                        break;
                                    }
                                }
                                if (k == roleCount)
                                {
                                    // Order is the same, collate the later readings up to the current order
                                    ReadOnlyCollection <ReadingOrderHasReading> readingLinks = ReadingOrderHasReading.GetLinksToReadingCollection(compareToOrder);
                                    int readingCount = readingLinks.Count;
                                    for (int l = 0; l < readingCount; ++l)
                                    {
                                        readingLinks[l].ReadingOrder = currentOrder;
                                    }
                                    orders[j] = null;
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #6
0
		/// <summary>
		/// Verify that all <see cref="ReadingOrder"/>s have unique <see cref="ReadingOrder.RoleCollection">role collections</see>
		/// </summary>
		/// <param name="element">A <see cref="FactType"/></param>
		private static void DelayValidateReadingOrderCollation(ModelElement element)
		{
			if (element.IsDeleted)
			{
				return;
			}
			FactType factType = (FactType)element;
			LinkedElementCollection<ReadingOrder> ordersCollection = factType.ReadingOrderCollection;
			int orderCount = ordersCollection.Count;
			if (orderCount > 1)
			{
				// Get all orders in a collatable form, starting by caching information locally
				// so it is easily accessed. Note that this will also change the collection we're
				// iterating so we need to be careful about changes.
				ReadingOrder[] orders = new ReadingOrder[orderCount];
				ordersCollection.CopyTo(orders, 0);
				LinkedElementCollection<RoleBase>[] roleCollections = new LinkedElementCollection<RoleBase>[orderCount];
				for (int i = 0; i < orderCount; ++i)
				{
					roleCollections[i] = orders[i].RoleCollection;
				}

				// Priority is top down, so we move later readings into a higher reading order
				for (int i = 0; i < orderCount; ++i)
				{
					ReadingOrder currentOrder = orders[i];
					for (int j = i + 1; j < orderCount; ++j)
					{
						ReadingOrder compareToOrder = orders[j];
						if (compareToOrder != null) // Will be null if it has already been recognized as a duplicate
						{
							// These should all have the same count, but it doesn't hurt to be defensive
							LinkedElementCollection<RoleBase> currentRoles = roleCollections[i];
							LinkedElementCollection<RoleBase> compareToRoles = roleCollections[j];
							int roleCount = currentRoles.Count;
							if (roleCount == compareToRoles.Count)
							{
								int k = 0;
								for (; k < roleCount; ++k)
								{
									if (currentRoles[k] != compareToRoles[k])
									{
										break;
									}
								}
								if (k == roleCount)
								{
									// Order is the same, collate the later readings up to the current order
									ReadOnlyCollection<ReadingOrderHasReading> readingLinks = ReadingOrderHasReading.GetLinksToReadingCollection(compareToOrder);
									int readingCount = readingLinks.Count;
									for (int l = 0; l < readingCount; ++l)
									{
										readingLinks[l].ReadingOrder = currentOrder;
									}
									orders[j] = null;
								}
							}
						}
					}
				}
			}
		}
            public static void ProcessFactType(FactType factType, INotifyElementAdded notifyAdded)
            {
                LinkedElementCollection <RoleBase> roleCollection = factType.RoleCollection;
                int roleCollectionCount = roleCollection.Count;

                if (roleCollectionCount == 1)
                {
                    // If we have a unary, binarize it
                    BinarizeUnary(factType, notifyAdded);
                    return;
                }
                else if (roleCollectionCount == 2)
                {
                    // If we have a binary that has an implicit boolean role in it, make sure it matches the pattern
                    Role implicitBooleanRole = GetImplicitBooleanRole(roleCollection);
                    if (implicitBooleanRole != null)
                    {
                        Role unaryRole = implicitBooleanRole.OppositeRole.Role;
                        Debug.Assert(unaryRole != null);
                        // Make sure the implicit boolean role has the same name as the unary role
                        implicitBooleanRole.Name = unaryRole.Name;
                        string implicitBooleanValueTypeName = GetImplicitBooleanValueTypeName(unaryRole);
                        if (implicitBooleanRole.RolePlayer.Name != implicitBooleanValueTypeName)
                        {
                            Dictionary <object, object> contextInfo = factType.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.Remove(duplicateSignaturesKey);
                                    addDuplicateSignaturesKey = true;
                                }
                                implicitBooleanRole.RolePlayer.Name = implicitBooleanValueTypeName;
                            }
                            finally
                            {
                                if (removeDuplicateNamesKey)
                                {
                                    contextInfo.Remove(duplicateNamesKey);
                                }
                                if (addDuplicateSignaturesKey)
                                {
                                    contextInfo[duplicateSignaturesKey] = null;
                                }
                            }
                        }
                        if (!ValidateConstraints(unaryRole, implicitBooleanRole) || !ValidateImplicitBooleanValueType(implicitBooleanRole.RolePlayer))
                        {
                            LinkedElementCollection <RoleBase> roles = factType.RoleCollection;
                            DebinarizeUnary(roles, false, notifyAdded);
                            // Append to the reading orders
                            LinkedElementCollection <ReadingOrder> readingOrders = factType.ReadingOrderCollection;
                            int readingOrderCount = readingOrders.Count;
                            for (int i = 0; i < readingOrderCount; ++i)
                            {
                                ReadingOrder order = readingOrders[i];
                                LinkedElementCollection <RoleBase> readingRoles = order.RoleCollection;
                                if (!readingRoles.Contains(implicitBooleanRole))
                                {
                                    readingRoles.Add(implicitBooleanRole);
                                    LinkedElementCollection <Reading> readings = order.ReadingCollection;
                                    int readingCount = readings.Count;
                                    for (int j = 0; j < readingCount; ++j)
                                    {
                                        readings[j].SetAutoText(readings[j].Text + " {1}");
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // If we have an n-ary, remove any implicit boolean roles in it
                    for (int i = roleCollectionCount - 1; i >= 0; --i)
                    {
                        Role implicitBooleanRole = roleCollection[i].Role;
                        if (implicitBooleanRole != null && implicitBooleanRole.RolePlayer != null && implicitBooleanRole.RolePlayer.IsImplicitBooleanValue)
                        {
                            DebinarizeUnary(factType.RoleCollection, true, notifyAdded);
                            break;
                        }
                    }
                }
            }
Beispiel #8
0
		private static string GenerateReadingText(string readingText, ReadingOrder order)
		{
			LinkedElementCollection<RoleBase> roles = order.RoleCollection;
			int roleCount = roles.Count;
			return Reading.ReplaceFields(
				readingText,
				delegate(int index)
				{
					if (index < roleCount)
					{
						ObjectType rolePlayer = roles[index].Role.RolePlayer;
						return (rolePlayer != null) ? rolePlayer.Name : ResourceStrings.ModelReadingEditorMissingRolePlayerText;
					}
					return null;
				});
		}