| 
     
      
      
      From: <mcu...@us...> - 2007-08-15 01:37:12
       
   | 
Revision: 1083
          http://orm.svn.sourceforge.net/orm/?rev=1083&view=rev
Author:   mcurland
Date:     2007-08-14 18:37:14 -0700 (Tue, 14 Aug 2007)
Log Message:
-----------
Various further tweaks to ORM/OIAL Bridge.
refs #327
Modified Paths:
--------------
    trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs
    trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs
    trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs
Modified: trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs	2007-08-15 01:06:22 UTC (rev 1082)
+++ trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs	2007-08-15 01:37:14 UTC (rev 1083)
@@ -10,35 +10,37 @@
 namespace Neumont.Tools.ORMToORMAbstractionBridge
 {
 	#region Chain calculator
-	sealed class UndecidedMappingChains
+	sealed class FactTypeChainer
 	{
-		private readonly FactTypeMappingListDictionary myUndecided;
+		private readonly FactTypeMappingDictionary myPredecidedManyToOneFactTypeMappings;
 		private readonly FactTypeMappingDictionary myPredecidedOneToOneFactTypeMappings;
+		private readonly FactTypeMappingListDictionary myUndecidedOneToOneFactTypeMappings;
 		private readonly ChainList myChains;
 
-		public UndecidedMappingChains(FactTypeMappingListDictionary undecided, FactTypeMappingDictionary predecidedOneToOneFactTypeMappings)
+		public FactTypeChainer(FactTypeMappingDictionary predecidedManyToOneFactTypeMappings, FactTypeMappingDictionary predecidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings)
 		{
 			myChains = new ChainList();
-			myUndecided = undecided;
+
+			myPredecidedManyToOneFactTypeMappings = predecidedManyToOneFactTypeMappings;
 			myPredecidedOneToOneFactTypeMappings = predecidedOneToOneFactTypeMappings;
+			myUndecidedOneToOneFactTypeMappings = undecidedOneToOneFactTypeMappings;
 		}
 
 		public int Run()
 		{
 			BuildChains();
-			//DeleteEmptyChains();
 
 			// Delete empty chains and find the largest chain.
 			int largestChainCount = 0;
 			for (int i = myChains.Count - 1; i >= 0; i--)
 			{
 				Chain chain = myChains[i];
-				if (chain.UndecidedFactTypeMappings.Count <= 0)
+				if (chain.UndecidedOneToOneFactTypeMappings.Count <= 0)
 				{
 					myChains.RemoveAt(i);
 					continue;
 				}
-				int chainCount = chain.FactTypeCount;
+				int chainCount = chain.OneToOneFactTypeCount;
 				if (chainCount > largestChainCount)
 				{
 					largestChainCount = chainCount;
@@ -55,13 +57,13 @@
 
 		private void BuildChains()
 		{
-			int factTypesCount = myUndecided.Count + myPredecidedOneToOneFactTypeMappings.Count;
+			int factTypesCount = myUndecidedOneToOneFactTypeMappings.Count + myPredecidedOneToOneFactTypeMappings.Count;
 			Dictionary<FactType, object> visitedFactTypes = new Dictionary<FactType, object>(factTypesCount);
 			Dictionary<ObjectType, object> visitedObjectTypes = new Dictionary<ObjectType, object>(factTypesCount * 2);
 
 
 			FactTypeMappingDictionary.Enumerator predecidedEnumerator = myPredecidedOneToOneFactTypeMappings.GetEnumerator();
-			FactTypeMappingListDictionary.Enumerator undecidedEnumerator = myUndecided.GetEnumerator();
+			FactTypeMappingListDictionary.Enumerator undecidedEnumerator = myUndecidedOneToOneFactTypeMappings.GetEnumerator();
 			while (true)
 			{
 				KeyValuePair<FactType, FactTypeMapping> predecidedPair;
@@ -92,7 +94,7 @@
 					}
 				}
 
-				// We're following a new path, so clear the current dictionary.
+				// We've found a new path, so create a chain for it.
 				Chain chain = new Chain();
 				myChains.Add(chain);
 
@@ -120,14 +122,18 @@
 
 				FactTypeMapping mapping;
 				FactTypeMappingList mappingList;
-				if (myUndecided.TryGetValue(factType, out mappingList))
+				if (myUndecidedOneToOneFactTypeMappings.TryGetValue(factType, out mappingList))
 				{
-					chain.UndecidedFactTypeMappings.Add(mappingList);
+					chain.UndecidedOneToOneFactTypeMappings.Add(mappingList);
 				}
 				else if (myPredecidedOneToOneFactTypeMappings.TryGetValue(factType, out mapping))
 				{
 					chain.PredecidedOneToOneFactTypeMappings.Add(mapping);
 				}
+				else if (myPredecidedManyToOneFactTypeMappings.TryGetValue(factType, out mapping))
+				{
+					chain.PredecidedManyToOneFactTypeMappings.Add(mapping);
+				}
 				else
 				{
 					continue;
@@ -146,12 +152,15 @@
 		}
 	}
 	#endregion
+
 	#region FactTypeMappingPermuter
 	sealed class FactTypeMappingPermuter
 	{
+		private readonly FactTypeMappingDictionary myPredecidedManyToOneFactTypeMappings;
+		private readonly FactTypeMappingDictionary myPredecidedOneToOneFactTypeMappings;
+		private readonly FactTypeMappingListDictionary myUndecidedOneToOneFactTypeMappings;
+
 		private readonly FactTypeMappingDictionary myDecidedFactTypeMappings;
-		private readonly FactTypeMappingDictionary myDecidedOneToOneFactTypeMappings;
-		private readonly FactTypeMappingListDictionary myUndecidedFactTypeMappings;
 
 		// Stores a list of object types that had been considered valid top-level, but was later found to be deeply mapped away
 		private readonly ObjectTypeDictionary myInvalidObjectTypes;
@@ -161,61 +170,45 @@
 		private readonly ObjectTypeDictionary myPossibleConceptTypes;
 
 
-		public FactTypeMappingPermuter(FactTypeMappingDictionary decidedFactTypeMappings, FactTypeMappingListDictionary undecidedFactTypeMappings)
+		public FactTypeMappingPermuter(FactTypeMappingDictionary predecidedManyToOneFactTypeMappings, FactTypeMappingDictionary predecidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings)
 		{
-			myDecidedFactTypeMappings = decidedFactTypeMappings;
-			myUndecidedFactTypeMappings = undecidedFactTypeMappings;
+			myPredecidedManyToOneFactTypeMappings = predecidedManyToOneFactTypeMappings;
+			myPredecidedOneToOneFactTypeMappings = predecidedOneToOneFactTypeMappings;
+			myUndecidedOneToOneFactTypeMappings = undecidedOneToOneFactTypeMappings;
 
-			myDecidedOneToOneFactTypeMappings = new FactTypeMappingDictionary(myDecidedFactTypeMappings.Count);
+			int oneToOneFactTypeCount = predecidedOneToOneFactTypeMappings.Count + undecidedOneToOneFactTypeMappings.Count;
+			myDecidedFactTypeMappings = new FactTypeMappingDictionary(predecidedManyToOneFactTypeMappings.Count + oneToOneFactTypeCount);
 
+			foreach (KeyValuePair<FactType, FactTypeMapping> pair in predecidedManyToOneFactTypeMappings)
+			{
+				myDecidedFactTypeMappings.Add(pair.Key, pair.Value);
+			}
+			foreach (KeyValuePair<FactType, FactTypeMapping> pair in predecidedOneToOneFactTypeMappings)
+			{
+				myDecidedFactTypeMappings.Add(pair.Key, pair.Value);
+			}
+
 			// Stores a list of object types that had been considered valid top-level, but was later found to be deeply mapped away
-			myInvalidObjectTypes = new ObjectTypeDictionary(myDecidedFactTypeMappings.Count);
-			myPossibleTopLevelConceptTypes = new ObjectTypeDictionary(myDecidedFactTypeMappings.Count);
-			myPossibleConceptTypes = new ObjectTypeDictionary(myDecidedFactTypeMappings.Count);
+			myInvalidObjectTypes = new ObjectTypeDictionary(oneToOneFactTypeCount);
+			myPossibleTopLevelConceptTypes = new ObjectTypeDictionary(oneToOneFactTypeCount);
+			myPossibleConceptTypes = new ObjectTypeDictionary(oneToOneFactTypeCount);
 		}
 
 		/// <summary>
 		/// Runs the permuter, and adds the final decided mapping to the decidedFactTypeMappings dictionary specified when this instance was constructed.
 		/// </summary>
-		public void Run()
+		public FactTypeMappingDictionary Run()
 		{
-			FindDecidedOneToOneMappings();
-
 			PermuteFactTypeMappings();
+			return myDecidedFactTypeMappings;
 		}
 
-		private void FindDecidedOneToOneMappings()
-		{	
-			FactTypeMapping mapping;
-			Role firstRole;
-			Role secondRole;
-			UniquenessConstraint firstRoleUniquenessConstraint;
-			UniquenessConstraint secondRoleUniquenessConstraint;
-			bool firstRoleIsUnique;
-			bool secondRoleIsUnique;
-			foreach (KeyValuePair<FactType, FactTypeMapping> pair in myDecidedFactTypeMappings)
-			{
-				mapping = pair.Value;
-				firstRole = mapping.FromRole;
-				secondRole = mapping.TowardsRole;
-				firstRoleUniquenessConstraint = (UniquenessConstraint)firstRole.SingleRoleAlethicUniquenessConstraint;
-				secondRoleUniquenessConstraint = (UniquenessConstraint)secondRole.SingleRoleAlethicUniquenessConstraint;
-				firstRoleIsUnique = (firstRoleUniquenessConstraint != null);
-				secondRoleIsUnique = (secondRoleUniquenessConstraint != null);
-
-				if (firstRoleIsUnique && secondRoleIsUnique)
-				{
-					myDecidedOneToOneFactTypeMappings.Add(pair.Key, pair.Value);
-				}
-			}
-		}
-
 		private void PermuteFactTypeMappings()
 		{
 			int largestChainCount;
-			// Break up the chains of contiguous undecided fact types
-			UndecidedMappingChains chains = new UndecidedMappingChains(myUndecidedFactTypeMappings, myDecidedOneToOneFactTypeMappings);
-			largestChainCount = chains.Run();
+			// Break up the chains of contiguous one-to-one fact types
+			FactTypeChainer chainer = new FactTypeChainer(myPredecidedManyToOneFactTypeMappings, myPredecidedOneToOneFactTypeMappings, myUndecidedOneToOneFactTypeMappings);
+			largestChainCount = chainer.Run();
 
 			// Perform one-time pass of top-level types for the decided mappings
 			PrecalculateDecidedConceptTypes();
@@ -227,7 +220,7 @@
 			Dictionary<ObjectType, object> deeplyMappedObjectTypes = new Dictionary<ObjectType, object>(largestChainCount);
 
 			// Loop through each chain, calculating the permutations.
-			foreach (Chain chain in chains.Chains)
+			foreach (Chain chain in chainer.Chains)
 			{
 				// Find the object types that we already know have deep mappings away from them.
 				foreach (FactTypeMapping decidedMapping in chain.PredecidedOneToOneFactTypeMappings)
@@ -240,9 +233,9 @@
 
 				// UNDONE: Eventually we should actually check this and warn the user if it would take too long on their machine.
 				// This would need to be calculated, though. A hard-coded limit wouldn't be appropriate here.
-				//int maxPermutations = CalculateMaxNumberOfPermutations(chain.UndecidedFactTypeMappings);
+				//int maxPermutations = CalculateMaxNumberOfPermutations(chain.UndecidedOneToOneFactTypeMappings);
 
-				PermuteFactTypeMappings(chain.PossiblePermutations, chain.UndecidedFactTypeMappings, newlyDecidedFactTypeMappings, deeplyMappedObjectTypes, 0);
+				PermuteFactTypeMappings(chain.PossiblePermutations, chain.UndecidedOneToOneFactTypeMappings, newlyDecidedFactTypeMappings, deeplyMappedObjectTypes, 0);
 				EliminateInvalidPermutations(chain);
 				CalculateTopLevelConceptTypes(chain);
 
@@ -259,6 +252,7 @@
 
 		private static FactTypeMapping FindDeepMappingAwayFromObjectType(ObjectType objectType, FactTypeMappingList predecidedOneToOneFactTypeMappings, FactTypeMappingList permutationFactTypeMappings)
 		{
+			// UNDONE: Figure out a way we can do this off of PlayedRoles instead, which should be faster.
 			foreach (FactTypeMapping mapping in predecidedOneToOneFactTypeMappings)
 			{
 				if (mapping.MappingDepth == MappingDepth.Deep && mapping.FromObjectType == objectType)
@@ -300,7 +294,7 @@
 		///		2. It is a subtype, or
 		///		3. Another object type (B) is mapped to it, and
 		///			a. There exists a role being mapped to object type A on which there are no constraints, or
-		///			b. There exists a role being mapped to object type A on which there is a uniqueness that is not preferred.
+		///			b. There exists a role being mapped to object type A on which there is not a preferred uniqueness.
 		/// 
 		/// A concept type is a top-level concept type when:
 		///		1. It is not deeply mapped towards any other concept type.
@@ -374,9 +368,6 @@
 		/// <param name="chain"></param>
 		private void CalculateTopLevelConceptTypes(Chain chain)
 		{
-#if PERMUTATION_DEBUG_OUTPUT
-			DateTime start = DateTime.Now;
-#endif
 			// The smallest overall mapping that we've found
 			int smallest = int.MaxValue;
 			// These dictionaries track the OTs that are temporarily removed or added for each permutation in the list
@@ -437,32 +428,6 @@
 					myPossibleConceptTypes.Remove(ot);
 				}
 			}
-#if PERMUTATION_DEBUG_OUTPUT
-			DateTime endat = DateTime.Now;
-			// Output values to a file
-			StreamWriter s = new StreamWriter("output_combinations.txt");
-			s.WriteLine("Smallest mapping: " + smallest.ToString());
-			s.WriteLine("# calculated as smallest (efficiency): " + mySmallestPermutationsList.Count);
-			s.WriteLine("Time: " + endat.Subtract(start).ToString());
-			/*
-			int p = 0;
-			foreach (FinalMappingState state in smallestList)
-			{
-				p++;
-				sw.WriteLine("\t" + p.ToString() + " (" + state.TopLevelConceptTypes.ToString() + " TLCTs)");
-				foreach (KeyValuePair<FactType, FactTypeMapping> pair in myDecidedFactTypeMappings)
-				{
-					FactTypeMapping mapping = pair.Value;
-					s.WriteLine("\t\t" + mapping.FromObjectType.ToString() + " to " + mapping.TowardsObjectType.ToString() + " (" + mapping.MappingType.ToString() + ")");
-				}
-				foreach (DecidedMappingStateEntry mapping in state.Mappings)
-				{
-					s.WriteLine("\t\t" + mapping.Mapping.FromObjectType.ToString() + " to " + mapping.Mapping.TowardsObjectType.ToString() + " (" + mapping.Mapping.MappingType.ToString() + ")");
-				}
-			}
-			 */
-			s.Close();
-#endif
 		}
 
 		/// <summary>
@@ -537,9 +502,9 @@
 		/// </param>
 		private static void EliminateInvalidPermutations(Chain chain)
 		{
-			Debug.Assert(chain.UndecidedFactTypeMappings.Count > 0);
+			Debug.Assert(chain.UndecidedOneToOneFactTypeMappings.Count > 0);
 
-			int factTypeCount = chain.FactTypeCount;
+			int factTypeCount = chain.OneToOneFactTypeCount;
 
 			FactTypeMappingList predecidedOneToOneFactTypeMappings = chain.PredecidedOneToOneFactTypeMappings;
 			PermutationList possiblePermutations = chain.PossiblePermutations;
@@ -624,4 +589,4 @@
 		}
 	}
 	#endregion
-}
\ No newline at end of file
+}
Modified: trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs	2007-08-15 01:06:22 UTC (rev 1082)
+++ trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs	2007-08-15 01:37:14 UTC (rev 1083)
@@ -287,31 +287,44 @@
 	[Serializable]
 	sealed class Chain
 	{
+		private readonly FactTypeMappingList myPredecidedManyToOneFactTypeMappings;
 		private readonly FactTypeMappingList myPredecidedOneToOneFactTypeMappings;
-		private readonly FactTypeMappingListList myUndecidedFactTypeMappings;
+		private readonly FactTypeMappingListList myUndecidedOneToOneFactTypeMappings;
 		private readonly PermutationList myPossiblePermutations;
 		private readonly PermutationList mySmallestPermutations;
 
 		public Chain()
 		{
+			myPredecidedManyToOneFactTypeMappings = new FactTypeMappingList();
 			myPredecidedOneToOneFactTypeMappings = new FactTypeMappingList();
-			myUndecidedFactTypeMappings = new FactTypeMappingListList();
+			myUndecidedOneToOneFactTypeMappings = new FactTypeMappingListList();
 			myPossiblePermutations = new PermutationList();
 			mySmallestPermutations = new PermutationList();
 		}
 
 		/// <summary>
-		/// Returns the number of FactTypes in this Chain.
+		/// Returns the number of one-to-one FactTypes in this Chain.
 		/// </summary>
-		public int FactTypeCount
+		public int OneToOneFactTypeCount
 		{
 			get
 			{
-				return myPredecidedOneToOneFactTypeMappings.Count + myUndecidedFactTypeMappings.Count;
+				return myPredecidedOneToOneFactTypeMappings.Count + myUndecidedOneToOneFactTypeMappings.Count;
 			}
 		}
 
 		/// <summary>
+		/// Many-to-one FactTypeMappings that are part of this chain but were decided before the permutation phase.
+		/// </summary>
+		public FactTypeMappingList PredecidedManyToOneFactTypeMappings
+		{
+			get
+			{
+				return myPredecidedManyToOneFactTypeMappings;
+			}
+		}
+
+		/// <summary>
 		/// One-to-one FactTypeMappings that are part of this chain but were decided before the permutation phase.
 		/// </summary>
 		public FactTypeMappingList PredecidedOneToOneFactTypeMappings
@@ -323,11 +336,11 @@
 		}
 
 		/// <summary>
-		/// The potential mappings of the undecided FactTypes that are in this Chain.
+		/// The potential mappings of the undecided one-to-one FactTypes that are in this Chain.
 		/// </summary>
-		public FactTypeMappingListList UndecidedFactTypeMappings
+		public FactTypeMappingListList UndecidedOneToOneFactTypeMappings
 		{
-			get { return myUndecidedFactTypeMappings; }
+			get { return myUndecidedOneToOneFactTypeMappings; }
 		}
 
 		/// <summary>
Modified: trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs
===================================================================
--- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs	2007-08-15 01:06:22 UTC (rev 1082)
+++ trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs	2007-08-15 01:37:14 UTC (rev 1083)
@@ -183,16 +183,18 @@
 		private void TransformORMtoOial()
 		{
 			ORMModel model = this.ORMModel;
-			FactTypeMappingDictionary decidedFactTypeMappings = null;
-			FactTypeMappingListDictionary undecidedFactTypeMappings = null;
 			LinkedElementCollection<FactType> modelFactTypes = model.FactTypeCollection;
 
-			InitialFactTypeMappings(modelFactTypes, out decidedFactTypeMappings, out undecidedFactTypeMappings);
-			FilterFactTypeMappings(decidedFactTypeMappings, undecidedFactTypeMappings);
+			FactTypeMappingDictionary decidedManyToOneFactTypeMappings = new FactTypeMappingDictionary();
+			FactTypeMappingDictionary decidedOneToOneFactTypeMappings = new FactTypeMappingDictionary();
+			FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings = new FactTypeMappingListDictionary();
 
-			FactTypeMappingPermuter permuter = new FactTypeMappingPermuter(decidedFactTypeMappings, undecidedFactTypeMappings);
-			permuter.Run();
+			PerformInitialFactTypeMappings(modelFactTypes, decidedManyToOneFactTypeMappings, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings);
+			FilterFactTypeMappings(decidedManyToOneFactTypeMappings, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings);
 
+			FactTypeMappingPermuter permuter = new FactTypeMappingPermuter(decidedManyToOneFactTypeMappings, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings);
+			FactTypeMappingDictionary decidedFactTypeMappings = permuter.Run();
+
 			GenerateOialModel(decidedFactTypeMappings);
 		}
 
@@ -200,13 +202,11 @@
 		/// Determines the obvious fact type mappings, and all other potential mappings.
 		/// </summary>
 		/// <param name="modelFactTypes">The <see cref="FactType"/> objects of the model</param>
-		/// <param name="decidedFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param>
-		/// <param name="undecidedFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param>
-		private void InitialFactTypeMappings(IList<FactType> modelFactTypes, out FactTypeMappingDictionary decidedFactTypeMappings, out FactTypeMappingListDictionary undecidedFactTypeMappings)
+		/// <param name="decidedManyToOneFactTypeMappings">The decided many-to-one <see cref="FactTypeMapping"/> objects.</param>
+		/// <param name="decidedOneToOneFactTypeMappings">The decided one-to-one <see cref="FactTypeMapping"/> objects.</param>
+		/// <param name="undecidedOneToOneFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param>
+		private void PerformInitialFactTypeMappings(LinkedElementCollection<FactType> modelFactTypes, FactTypeMappingDictionary decidedManyToOneFactTypeMappings, FactTypeMappingDictionary decidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings)
 		{
-			decidedFactTypeMappings = new FactTypeMappingDictionary();
-			undecidedFactTypeMappings = new FactTypeMappingListDictionary();
-
 			// For each fact type in the model...
 			foreach (FactType factType in modelFactTypes)
 			{
@@ -225,7 +225,7 @@
 					// Map deeply toward the supertype.
 					FactTypeMapping factTypeMapping = new FactTypeMapping(subtypeFact, subtypeRole, supertypeRole, MappingDepth.Deep);
 
-					decidedFactTypeMappings.Add(subtypeFact, factTypeMapping);
+					decidedOneToOneFactTypeMappings.Add(subtypeFact, factTypeMapping);
 				}
 				else
 				{
@@ -242,28 +242,31 @@
 					bool firstRoleIsUnique = (firstRoleUniquenessConstraint != null);
 					bool secondRoleIsUnique = (secondRoleUniquenessConstraint != null);
 
+					// We don't need to worry about shallow mappings towards preferred identifiers on many-to-ones, since the preferred
+					// identifier pattern ensures that these cases will always map towards the object type being identified anyway.
+
 					// If only firstRole is unique...
 					if (firstRoleIsUnique && !secondRoleIsUnique)
 					{
 						// Shallow map toward firstRolePlayer.
 						FactTypeMapping factTypeMapping = new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow);
 
-						decidedFactTypeMappings.Add(factType, factTypeMapping);
+						decidedManyToOneFactTypeMappings.Add(factType, factTypeMapping);
 					}
 					else if (!firstRoleIsUnique && secondRoleIsUnique) // ...only secondRole is unique...
 					{
 						// Shallow map toward secondRolePlayer.
 						FactTypeMapping factTypeMapping = new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow);
 
-						decidedFactTypeMappings.Add(factType, factTypeMapping);
+						decidedManyToOneFactTypeMappings.Add(factType, factTypeMapping);
 					}
 					else if (firstRoleIsUnique && secondRoleIsUnique) // ...both roles are unique...
 					{
-						bool firstRoleIsMandatory = null != firstRole.SingleRoleAlethicMandatoryConstraint;
-						bool secondRoleIsMandatory = null != secondRole.SingleRoleAlethicMandatoryConstraint;
+						bool firstRoleIsMandatory = (firstRole.SingleRoleAlethicMandatoryConstraint != null);
+						bool secondRoleIsMandatory = (secondRole.SingleRoleAlethicMandatoryConstraint != null);
 
 						// If this is a ring fact type...
-						if (firstRolePlayer.Id == secondRolePlayer.Id)
+						if (firstRolePlayer == secondRolePlayer)
 						{
 							// If only firstRole is mandatory...
 							if (firstRoleIsMandatory && !secondRoleIsMandatory)
@@ -271,60 +274,88 @@
 								// Shallow map toward firstRolePlayer (mandatory role player).
 								FactTypeMapping factTypeMapping = new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow);
 
-								decidedFactTypeMappings.Add(factType, factTypeMapping);
+								decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping);
 							}
 							else if (!firstRoleIsMandatory && secondRoleIsMandatory) // ...only secondRole is mandatory...
 							{
 								// Shallow map toward secondRolePlayer (mandatory role player).
 								FactTypeMapping factTypeMapping = new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow);
 
-								decidedFactTypeMappings.Add(factType, factTypeMapping);
+								decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping);
 							}
 							else // ...otherwise...
 							{
 								// Shallow map toward firstRolePlayer.
 								FactTypeMapping factTypeMapping = new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow);
 
-								decidedFactTypeMappings.Add(factType, factTypeMapping);
+								decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping);
 							}
 						}
 						else // ...not a ring fact type...
 						{
+							// These are used to make sure that we never shallowly map towards a preferred identifier.
+							bool firstRoleIsUniqueAndPreferred = firstRoleIsUnique && firstRoleUniquenessConstraint.IsPreferred;
+							bool secondRoleIsUniqueAndPreferred = secondRoleIsUnique && secondRoleUniquenessConstraint.IsPreferred;
+
 							FactTypeMappingList potentialFactTypeMappings = new FactTypeMappingList();
 
 							// If neither role is mandatory...
-							if (!(firstRoleIsMandatory || secondRoleIsMandatory))
+							if (!firstRoleIsMandatory && !secondRoleIsMandatory)
 							{
-								// Shallow map toward firstRolePlayer.
-								potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow));
-								// Shallow map toward secondRolePlayer.
-								potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow));
+								// If firstRole is not preferred...
+								if (!firstRoleIsUniqueAndPreferred)
+								{
+									// Shallow map toward firstRolePlayer.
+									potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow));
+								}
+
+								// If seccondRole is not preferred...
+								if (!secondRoleIsUniqueAndPreferred)
+								{
+									// Shallow map toward secondRolePlayer.
+									potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow));
+								}
 							}
-							// If exactly one role is mandatory, we only allow shallow towards that role or deep away from it.
-							// This is an optimization, but at this point I don't remember with 100% confidence that it is correct.
-							// -Kevin
 							else if (firstRoleIsMandatory && !secondRoleIsMandatory) // ...only firstRole is mandatory...
 							{
-								// Shallow map toward firstRolePlayer.
-								potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow));
+								// If firstRole is not preferred...
+								if (!firstRoleIsUniqueAndPreferred)
+								{
+									// Shallow map toward firstRolePlayer.
+									potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow));
+								}
+
+								// If seccondRole is not preferred...
+								if (!secondRoleIsUniqueAndPreferred)
+								{
+									// Shallow map toward secondRolePlayer.
+									potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow));
+								}
+
 								// Deep map toward secondRolePlayer.
 								potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Deep));
 							}
 							else if (!firstRoleIsMandatory && secondRoleIsMandatory) // ...only secondRole is mandatory...
 							{
+								// If firstRole is not preferred...
+								if (!firstRoleIsUniqueAndPreferred)
+								{
+									// Shallow map toward firstRolePlayer.
+									potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow));
+								}
+
 								// Deep map toward firstRolePlayer.
 								potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Deep));
-								// Shallow map toward secondRolePlayer.
-								potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow));
+
+								// If seccondRole is not preferred...
+								if (!secondRoleIsUniqueAndPreferred)
+								{
+									// Shallow map toward secondRolePlayer.
+									potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow));
+								}
 							}
 							else // ...both roles are mandatory...
 							{
-								bool firstRoleIsUniqueAndPreferred = firstRoleIsUnique && firstRoleUniquenessConstraint.IsPreferred;
-								bool secondRoleIsUniqueAndPreferred = secondRoleIsUnique && secondRoleUniquenessConstraint.IsPreferred;
-
-								// We do this to make sure that we never shallowly map towards a preferred identifier.
-								// UNDONE: Should we be doing this for the less-than-two mandatories cases as well? -Kevin
-
 								// If firstRole is not preferred...
 								if (!firstRoleIsUniqueAndPreferred)
 								{
@@ -341,11 +372,20 @@
 
 								// Deep map toward firstRolePlayer.
 								potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Deep));
+
 								// Deep map toward secondRolePlayer.
 								potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Deep));
 							}
 
-							undecidedFactTypeMappings.Add(factType, potentialFactTypeMappings);
+							Debug.Assert(potentialFactTypeMappings.Count > 0);
+							if (potentialFactTypeMappings.Count == 1)
+							{
+								decidedOneToOneFactTypeMappings.Add(factType, potentialFactTypeMappings[0]);
+							}
+							else
+							{
+								undecidedOneToOneFactTypeMappings.Add(factType, potentialFactTypeMappings);
+							}
 						}
 					}
 				}
@@ -355,16 +395,17 @@
 		/// <summary>
 		/// Runs various algorithms on the undecided fact type mappings in an attempt to decide as many as possible.
 		/// </summary>
-		/// <param name="decidedFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param>
-		/// <param name="undecidedFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param>
-		private void FilterFactTypeMappings(FactTypeMappingDictionary decidedFactTypeMappings, FactTypeMappingListDictionary undecidedFactTypeMappings)
+		/// <param name="decidedManyToOneFactTypeMappings">The decided many-to-one <see cref="FactTypeMapping"/> objects.</param>
+		/// <param name="decidedOneToOneFactTypeMappings">The decided one-to-one <see cref="FactTypeMapping"/> objects.</param>
+		/// <param name="undecidedOneToOneFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param>
+		private void FilterFactTypeMappings(FactTypeMappingDictionary decidedManyToOneFactTypeMappings, FactTypeMappingDictionary decidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings)
 		{
-			RemoveImpossiblePotentialFactTypeMappings(decidedFactTypeMappings, undecidedFactTypeMappings);
+			RemoveImpossiblePotentialFactTypeMappings(decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings);
 
 			int changeCount = 0;
 			do
 			{
-				changeCount = MapTrivialOneToOneFactTypesWithTwoMandatories(decidedFactTypeMappings, undecidedFactTypeMappings);
+				changeCount = MapTrivialOneToOneFactTypesWithTwoMandatories(decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings);
 			} while (changeCount > 0);
 		}
 
@@ -373,14 +414,14 @@
 		/// Filters out de...
 
[truncated message content] | 
| 
     
      
      
      From: <mcu...@us...> - 2007-08-20 21:47:17
       
   | 
Revision: 1090
          http://orm.svn.sourceforge.net/orm/?rev=1090&view=rev
Author:   mcurland
Date:     2007-08-20 14:47:19 -0700 (Mon, 20 Aug 2007)
Log Message:
-----------
Added additional rules for propagating ORM model changes to the abstraction model. Mandatory changes and uniqueness constraint deletion cases that do not modify absorption are handled incrementally. Preferred identifier changes fully regenerate. refs #327
Modified Paths:
--------------
    trunk/Oial/ORMOialBridge/ModificationTracker.cs
    trunk/Oial/ORMOialBridge/ORMElementGateway.cs
    trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs
    trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml
    trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs
Modified: trunk/Oial/ORMOialBridge/ModificationTracker.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ModificationTracker.cs	2007-08-20 21:45:28 UTC (rev 1089)
+++ trunk/Oial/ORMOialBridge/ModificationTracker.cs	2007-08-20 21:47:19 UTC (rev 1090)
@@ -114,6 +114,59 @@
 					}
 				}
 			}
+			/// <summary>
+			/// RolePlayerChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier)
+			/// Changing the preferred identifier for an <see cref="ObjectType"/> is considered to
+			/// be a significant change until we support full incremental tracking.
+			/// </summary>
+			private static void PreferredIdentifierRolePlayerChangedRule(RolePlayerChangedEventArgs e)
+			{
+				// UNDONE: Incremental changes, propagate changes to Uniqueness.IsPreferred property
+				EntityTypeHasPreferredIdentifier link = (EntityTypeHasPreferredIdentifier)e.ElementLink;
+				if (e.DomainRole.Id == EntityTypeHasPreferredIdentifier.PreferredIdentifierForDomainRoleId)
+				{
+					SignificantObjectTypeChange((ObjectType)e.OldRolePlayer);
+				}
+				SignificantObjectTypeChange(link.PreferredIdentifierFor);
+			}
+			/// <summary>
+			/// DeleteRule: typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier)
+			/// If an <see cref="ObjectType"/> is alive after gateway processing when its preferred identifier
+			/// is deleted then it needs to be reprocessed.
+			/// </summary>
+			private static void PreferredIdentifierDeletedRule(ElementDeletedEventArgs e)
+			{
+				// UNDONE: Incremental If this gets passed the gateway and is not excluded,
+				// then it changed from an EntityType to a ValueType
+				ObjectType objectType = ((EntityTypeHasPreferredIdentifier)e.ModelElement).PreferredIdentifierFor;
+				if (!objectType.IsDeleted)
+				{
+					SignificantObjectTypeChange(objectType);
+				}
+			}
+			/// <summary>
+			/// RolePlayerChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole)
+			/// Revalidate the model when the <see cref="ObjectType">role player</see> of a <see cref="Role"/>
+			/// is changed.
+			/// </summary>
+			private static void RolePlayerRolePlayerChangedRule(RolePlayerChangedEventArgs e)
+			{
+				// UNDONE: Incremental changes will not be as severe here. Note that adding
+				// and deleting role players already triggers the correct actions in the
+				// gateway rules. However, a change where none of the parties are excluded
+				// simply needs to regenerate for now.
+				ObjectTypePlaysRole link = (ObjectTypePlaysRole)e.ElementLink;
+				if (e.DomainRole.Id == ObjectTypePlaysRole.PlayedRoleDomainRoleId)
+				{
+					SignificantFactTypeChange(((Role)e.OldRolePlayer).FactType);
+				}
+				else
+				{
+					SignificantObjectTypeChange((ObjectType)e.OldRolePlayer);
+				}
+				SignificantObjectTypeChange(link.RolePlayer);
+				SignificantFactTypeChange(link.PlayedRole.FactType);
+			}
 			#endregion // ORM modification rule methods
 			#region Bridge deletion rule methods
 			/// <summary>
@@ -154,6 +207,20 @@
 					AddTransactedModelElement(conceptType, ModelElementModification.AbstractionElementDetached);
 				}
 			}
+			/// <summary>
+			/// DeleteRule: typeof(UniquenessIsForUniquenessConstraint)
+			/// </summary>
+			private static void UniquenessBridgeDetachedRule(ElementDeletedEventArgs e)
+			{
+				Uniqueness uniqueness = ((UniquenessIsForUniquenessConstraint)e.ModelElement).Uniqueness;
+				if (!uniqueness.IsDeleted)
+				{
+					// We don't want to rebuild the model for this case. Any significant
+					// change that affects the absorption pattern will remove it, and
+					// there are no cases where we need to keep it. Just propagate.
+					uniqueness.Delete();
+				}
+			}
 			#endregion // Bridge deletion rule methods
 			#region General validation helper methods
 			private static bool IsRelevantConstraint(IConstraint constraint)
@@ -198,7 +265,10 @@
 							MappingMandatoryPattern endMandatoryPattern = mapToRole.MandatoryPattern;
 							if (endMandatoryPattern != startMandatoryPattern)
 							{
-								// UNDONE: Propagate IsMandatory changes directly to the model
+								foreach (ConceptTypeChild child in ConceptTypeChildHasPathFactType.GetConceptTypeChild(factType))
+								{
+									ValidateMandatory(child, startMandatoryPattern, endMandatoryPattern);
+								}
 							}
 						}
 						else
@@ -209,6 +279,88 @@
 					}
 				}
 			}
+			/// <summary>
+			/// The <see cref="ConceptTypeChild.IsMandatory">IsMandatory</see> setting may
+			/// have change, revalidate if necessary.
+			/// </summary>
+			/// <param name="child">The <see cref="ConceptTypeChild"/> element to validate</param>
+			/// <param name="oldMandatory">The old mandatory pattern for any <see cref="FactType"/> in the path.</param>
+			/// <param name="newMandatory">The new mandatory pattern for any <see cref="FactType"/> in the path.</param>
+			private static void ValidateMandatory(ConceptTypeChild child, MappingMandatoryPattern oldMandatory, MappingMandatoryPattern newMandatory)
+			{
+				// We pre filter this and don't both to notify unless a change is possible
+				bool mightHaveChanged = false;
+				if (child.IsMandatory)
+				{
+					switch (oldMandatory)
+					{
+						case MappingMandatoryPattern.BothRolesMandatory:
+						case MappingMandatoryPattern.TowardsRoleMandatory:
+							switch (newMandatory)
+							{
+								case MappingMandatoryPattern.OppositeRoleMandatory:
+								case MappingMandatoryPattern.NotMandatory:
+									mightHaveChanged = true;
+									break;
+							}
+							break;
+					}
+				}
+				else
+				{
+					switch (oldMandatory)
+					{
+						case MappingMandatoryPattern.NotMandatory:
+						case MappingMandatoryPattern.OppositeRoleMandatory:
+							switch (newMandatory)
+							{
+								case MappingMandatoryPattern.BothRolesMandatory:
+								case MappingMandatoryPattern.TowardsRoleMandatory:
+									mightHaveChanged = true;
+									break;
+							}
+							break;
+					}
+				}
+				if (mightHaveChanged)
+				{
+					FrameworkDomainModel.DelayValidateElement(child, ValidateMandatoryDelayed);
+				}
+			}
+			[DelayValidatePriority(ValidationPriority.ValidateMandatory)]
+			private static void ValidateMandatoryDelayed(ModelElement element)
+			{
+				if (!element.IsDeleted)
+				{
+					ConceptTypeChild child = (ConceptTypeChild)element;
+					bool newMandatory = true;
+					foreach (FactType factType in ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(child))
+					{
+						FactTypeMapsTowardsRole towardsRoleLink = FactTypeMapsTowardsRole.GetLinkToTowardsRole(factType);
+						if (null == towardsRoleLink)
+						{
+							newMandatory = false;
+							break;
+						}
+						else
+						{
+							switch (towardsRoleLink.MandatoryPattern)
+							{
+								case MappingMandatoryPattern.None:
+								case MappingMandatoryPattern.NotMandatory:
+								case MappingMandatoryPattern.OppositeRoleMandatory:
+									newMandatory = false;
+									break;
+							}
+							if (!newMandatory)
+							{
+								break;
+							}
+						}
+					}
+					child.IsMandatory = newMandatory;
+				}
+			}
 			private static void SignificantFactTypeChange(FactType factType)
 			{
 				if (factType != null &&
Modified: trunk/Oial/ORMOialBridge/ORMElementGateway.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ORMElementGateway.cs	2007-08-20 21:45:28 UTC (rev 1089)
+++ trunk/Oial/ORMOialBridge/ORMElementGateway.cs	2007-08-20 21:47:19 UTC (rev 1090)
@@ -31,20 +31,6 @@
 		/// </summary>
 		private static partial class ORMElementGateway
 		{
-			#region ValidationPriority enum
-			/// <summary>
-			/// DelayValidate ordering constants
-			/// </summary>
-			private static class ValidationPriority
-			{
-				public const int NewObjectType = -100;
-				public const int ReconsiderObjectType = -90;
-				public const int NewFactType = -80;
-				public const int ReconsiderFactType = -70;
-				public const int RemoveExcludedBridgeRelationships = -60;
-				public const int AddElement = -50;
-			}
-			#endregion // ValidationPriority enum
 			#region Public methods
 			/// <summary>
 			/// Returns <see langword="true"/> if an element is currently excluded from 
@@ -168,7 +154,7 @@
 			}
 			#endregion // ShouldConsider* methods, determine if an element should be filtered
 			#region FilterNew* methods, determine filtering for newly created elements
-			[DelayValidatePriority(ValidationPriority.NewFactType)]
+			[DelayValidatePriority(ValidationPriority.GatewayNewFactType)]
 			private static void FilterNewFactType(ModelElement element)
 			{
 				ModelHasFactType link = element as ModelHasFactType;
@@ -182,7 +168,7 @@
 					ExcludeFactType(factType);
 				}
 			}
-			[DelayValidatePriority(ValidationPriority.NewObjectType)]
+			[DelayValidatePriority(ValidationPriority.GatewayNewObjectType)]
 			private static void FilterNewObjectType(ModelElement element)
 			{
 				ModelHasObjectType link = element as ModelHasObjectType;
@@ -219,7 +205,7 @@
 					}
 				}
 			}
-			[DelayValidatePriority(ValidationPriority.ReconsiderFactType)]
+			[DelayValidatePriority(ValidationPriority.GatewayReconsiderFactType)]
 			private static void FilterModifiedFactTypeDelayed(ModelElement element)
 			{
 				if (!element.IsDeleted)
@@ -260,7 +246,7 @@
 					FrameworkDomainModel.DelayValidateElement(objectType, FilterModifiedObjectTypeDelayed);
 				}
 			}
-			[DelayValidatePriority(ValidationPriority.ReconsiderObjectType)]
+			[DelayValidatePriority(ValidationPriority.GatewayReconsiderObjectType)]
 			private static void FilterModifiedObjectTypeDelayed(ModelElement element)
 			{
 				if (!element.IsDeleted)
@@ -374,7 +360,7 @@
 			/// Delay validation callback used when the state of a <see cref="FactType"/>
 			/// has changed such that it may or may not be included in the abstraction model.
 			/// </summary>
-			[DelayValidatePriority(ValidationPriority.AddElement)]
+			[DelayValidatePriority(ValidationPriority.GatewayAddElement)]
 			private static void AddFactTypeDelayed(ModelElement element)
 			{
 				if (!element.IsDeleted)
@@ -404,7 +390,7 @@
 			/// Delay validation callback used when the state of a <see cref="ObjectType"/>
 			/// has changed such that it may or may not be included in the abstraction model.
 			/// </summary>
-			[DelayValidatePriority(ValidationPriority.AddElement)]
+			[DelayValidatePriority(ValidationPriority.GatewayAddElement)]
 			private static void AddObjectTypeDelayed(ModelElement element)
 			{
 				if (!element.IsDeleted)
@@ -429,7 +415,7 @@
 			{
 				FrameworkDomainModel.DelayValidateElement(e.ModelElement, ExclusionAdded);
 			}
-			[DelayValidatePriority(ValidationPriority.RemoveExcludedBridgeRelationships)]
+			[DelayValidatePriority(ValidationPriority.GatewayRemoveExcludedBridgeRelationships)]
 			private static void ExclusionAdded(ModelElement element)
 			{
 				ExcludedORMModelElement link = (ExcludedORMModelElement)element;
Modified: trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs	2007-08-20 21:45:28 UTC (rev 1089)
+++ trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs	2007-08-20 21:47:19 UTC (rev 1090)
@@ -51,7 +51,11 @@
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("ConstraintRoleDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("ObjectTypeChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("ORMModelChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
-						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("SetConstraintChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic)};
+						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("PreferredIdentifierDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("PreferredIdentifierRolePlayerChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("RolePlayerRolePlayerChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("SetConstraintChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+						typeof(AbstractionModelIsForORMModel).GetNestedType("ModificationTracker", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("UniquenessBridgeDetachedRuleClass", BindingFlags.Public | BindingFlags.NonPublic)};
 					ORMToORMAbstractionBridgeDomainModel.myCustomDomainModelTypes = retVal;
 					System.Diagnostics.Debug.Assert(Array.IndexOf<Type>(retVal, null) < 0, "One or more rule types failed to resolve. The file and/or package will fail to load.");
 				}
@@ -85,7 +89,7 @@
 		{
 			Microsoft.VisualStudio.Modeling.RuleManager ruleManager = store.RuleManager;
 			Type[] disabledRuleTypes = ORMToORMAbstractionBridgeDomainModel.CustomDomainModelTypes;
-			for (int i = 0; i < 18; ++i)
+			for (int i = 0; i < 22; ++i)
 			{
 				ruleManager.EnableRule(disabledRuleTypes[i]);
 			}
@@ -572,6 +576,84 @@
 					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.ORMModelChangedRule");
 				}
 			}
+			[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier))]
+			private sealed class PreferredIdentifierDeletedRuleClass : Microsoft.VisualStudio.Modeling.DeleteRule
+			{
+				[System.Diagnostics.DebuggerStepThrough()]
+				public PreferredIdentifierDeletedRuleClass()
+				{
+					base.IsEnabled = false;
+				}
+				/// <summary>
+				/// Provide the following method in class: 
+				/// Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker
+				/// /// <summary>
+				/// /// DeleteRule: typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier)
+				/// /// </summary>
+				/// private static void PreferredIdentifierDeletedRule(ElementDeletedEventArgs e)
+				/// {
+				/// }
+				/// </summary>
+				[System.Diagnostics.DebuggerStepThrough()]
+				public override void ElementDeleted(Microsoft.VisualStudio.Modeling.ElementDeletedEventArgs e)
+				{
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.PreferredIdentifierDeletedRule");
+					ModificationTracker.PreferredIdentifierDeletedRule(e);
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.PreferredIdentifierDeletedRule");
+				}
+			}
+			[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier))]
+			private sealed class PreferredIdentifierRolePlayerChangedRuleClass : Microsoft.VisualStudio.Modeling.RolePlayerChangeRule
+			{
+				[System.Diagnostics.DebuggerStepThrough()]
+				public PreferredIdentifierRolePlayerChangedRuleClass()
+				{
+					base.IsEnabled = false;
+				}
+				/// <summary>
+				/// Provide the following method in class: 
+				/// Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker
+				/// /// <summary>
+				/// /// RolePlayerChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier)
+				/// /// </summary>
+				/// private static void PreferredIdentifierRolePlayerChangedRule(RolePlayerChangedEventArgs e)
+				/// {
+				/// }
+				/// </summary>
+				[System.Diagnostics.DebuggerStepThrough()]
+				public override void RolePlayerChanged(Microsoft.VisualStudio.Modeling.RolePlayerChangedEventArgs e)
+				{
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ElementLink.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.PreferredIdentifierRolePlayerChangedRule");
+					ModificationTracker.PreferredIdentifierRolePlayerChangedRule(e);
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ElementLink.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.PreferredIdentifierRolePlayerChangedRule");
+				}
+			}
+			[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole))]
+			private sealed class RolePlayerRolePlayerChangedRuleClass : Microsoft.VisualStudio.Modeling.RolePlayerChangeRule
+			{
+				[System.Diagnostics.DebuggerStepThrough()]
+				public RolePlayerRolePlayerChangedRuleClass()
+				{
+					base.IsEnabled = false;
+				}
+				/// <summary>
+				/// Provide the following method in class: 
+				/// Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker
+				/// /// <summary>
+				/// /// RolePlayerChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole)
+				/// /// </summary>
+				/// private static void RolePlayerRolePlayerChangedRule(RolePlayerChangedEventArgs e)
+				/// {
+				/// }
+				/// </summary>
+				[System.Diagnostics.DebuggerStepThrough()]
+				public override void RolePlayerChanged(Microsoft.VisualStudio.Modeling.RolePlayerChangedEventArgs e)
+				{
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ElementLink.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.RolePlayerRolePlayerChangedRule");
+					ModificationTracker.RolePlayerRolePlayerChangedRule(e);
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ElementLink.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.RolePlayerRolePlayerChangedRule");
+				}
+			}
 			[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.SetConstraint))]
 			private sealed class SetConstraintChangedRuleClass : Microsoft.VisualStudio.Modeling.ChangeRule
 			{
@@ -598,6 +680,32 @@
 					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.SetConstraintChangedRule");
 				}
 			}
+			[Microsoft.VisualStudio.Modeling.RuleOn(typeof(UniquenessIsForUniquenessConstraint))]
+			private sealed class UniquenessBridgeDetachedRuleClass : Microsoft.VisualStudio.Modeling.DeleteRule
+			{
+				[System.Diagnostics.DebuggerStepThrough()]
+				public UniquenessBridgeDetachedRuleClass()
+				{
+					base.IsEnabled = false;
+				}
+				/// <summary>
+				/// Provide the following method in class: 
+				/// Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker
+				/// /// <summary>
+				/// /// DeleteRule: typeof(UniquenessIsForUniquenessConstraint)
+				/// /// </summary>
+				/// private static void UniquenessBridgeDetachedRule(ElementDeletedEventArgs e)
+				/// {
+				/// }
+				/// </summary>
+				[System.Diagnostics.DebuggerStepThrough()]
+				public override void ElementDeleted(Microsoft.VisualStudio.Modeling.ElementDeletedEventArgs e)
+				{
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.UniquenessBridgeDetachedRule");
+					ModificationTracker.UniquenessBridgeDetachedRule(e);
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ModificationTracker.UniquenessBridgeDetachedRule");
+				}
+			}
 		}
 	}
 	#endregion // Rule classes for AbstractionModelIsForORMModel.ModificationTracker
Modified: trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml
===================================================================
--- trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml	2007-08-20 21:45:28 UTC (rev 1089)
+++ trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml	2007-08-20 21:47:19 UTC (rev 1090)
@@ -80,9 +80,21 @@
 			<arg:ChangeRule methodName="ORMModelChangedRule">
 				<arg:RuleOn targetType="ORMModel" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
 			</arg:ChangeRule>
+			<arg:DeleteRule methodName="PreferredIdentifierDeletedRule">
+				<arg:RuleOn targetType="EntityTypeHasPreferredIdentifier" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
+			</arg:DeleteRule>
+			<arg:RolePlayerChangeRule methodName="PreferredIdentifierRolePlayerChangedRule">
+				<arg:RuleOn targetType="EntityTypeHasPreferredIdentifier" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
+			</arg:RolePlayerChangeRule>
+			<arg:RolePlayerChangeRule methodName="RolePlayerRolePlayerChangedRule">
+				<arg:RuleOn targetType="ObjectTypePlaysRole" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
+			</arg:RolePlayerChangeRule>
 			<arg:ChangeRule methodName="SetConstraintChangedRule">
 				<arg:RuleOn targetType="SetConstraint" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
 			</arg:ChangeRule>
+			<arg:DeleteRule methodName="UniquenessBridgeDetachedRule">
+				<arg:RuleOn targetType="UniquenessIsForUniquenessConstraint"/>
+			</arg:DeleteRule>
 		</arg:RuleContainer>
 	</arg:Model>
 </arg:Rules>
\ No newline at end of file
Modified: trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs
===================================================================
--- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs	2007-08-20 21:45:28 UTC (rev 1089)
+++ trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs	2007-08-20 21:47:19 UTC (rev 1090)
@@ -15,6 +15,53 @@
 {
 	public partial class AbstractionModelIsForORMModel
 	{
+		#region ValidationPriority enum
+		/// <summary>
+		/// DelayValidate ordering constants. Handles non-zero values for
+		/// validation methods in this class and nested classes.
+		/// </summary>
+		private static class ValidationPriority
+		{
+			/// <summary>
+			/// A new <see cref="ObjectType"/> has been added to the ORM model, establish
+			/// gateway exclusion relationships.
+			/// </summary>
+			public const int GatewayNewObjectType = -100;
+			/// <summary>
+			/// An <see cref="ObjectType"/> has been modified in the ORM model, establish
+			/// gateway exclusion relationships.
+			/// </summary>
+			public const int GatewayReconsiderObjectType = -90;
+			/// <summary>
+			/// A <see cref="FactType"/> has been modified in the ORM model, establish
+			/// gateway exclusion relationships.
+			/// </summary>
+			public const int GatewayNewFactType = -80;
+			/// <summary>
+			/// A <see cref="FactType"/> has been modified in the ORM model, establish
+			/// gateway exclusion relationships.
+			/// </summary>
+			public const int GatewayReconsiderFactType = -70;
+			/// <summary>
+			/// Gateway exclusion relationships have been added, remove other existing
+			/// bridge relationships
+			/// </summary>
+			public const int GatewayRemoveExcludedBridgeRelationships = -60;
+			/// <summary>
+			/// A new element has been added and passed gateway filtering
+			/// </summary>
+			public const int GatewayAddElement = -50;
+			/// <summary>
+			/// Validate the model. Current rebuilds the entire model.
+			/// </summary>
+			public const int ValidateModel = 100;
+			/// <summary>
+			/// Reset mandatory properties. This is done after ValidateModel
+			/// so that we don't waste time 
+			/// </summary>
+			public const int ValidateMandatory = 110;
+		}
+		#endregion // ValidationPriority enum
 		#region Element tracking transaction support
 		#region ModelElementModification enum
 		/// <summary>
@@ -77,7 +124,7 @@
 		/// Delays the validate model.
 		/// </summary>
 		/// <param name="element">The element.</param>
-		[DelayValidatePriority(100)]
+		[DelayValidatePriority(ValidationPriority.ValidateModel)]
 		private static void DelayValidateModel(ModelElement element)
 		{
 			Dictionary<object, object> contextDictionary = element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
 | 
| 
     
      
      
      From: <mcu...@us...> - 2007-09-01 19:12:15
       
   | 
Revision: 1110
          http://orm.svn.sourceforge.net/orm/?rev=1110&view=rev
Author:   mcurland
Date:     2007-09-01 12:12:14 -0700 (Sat, 01 Sep 2007)
Log Message:
-----------
Subtypes with no resolvable preferred identifier were considered eligible for absorption. Modify ORMElementGateway to block object types that do not resolve to a preferred identifier. refs #327
Modified Paths:
--------------
    trunk/Oial/ORMOialBridge/ORMElementGateway.cs
    trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs
    trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml
Modified: trunk/Oial/ORMOialBridge/ORMElementGateway.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ORMElementGateway.cs	2007-09-01 19:01:35 UTC (rev 1109)
+++ trunk/Oial/ORMOialBridge/ORMElementGateway.cs	2007-09-01 19:12:14 UTC (rev 1110)
@@ -133,6 +133,40 @@
 							}
 						}
 					}
+					else if (!objectType.IsValueType)
+					{
+						// If this is a subtype, then we need to resolve
+						// the preferred identifier back to a non-excluded super type
+						ObjectType preferridentifierFrom = null;
+						ObjectType.WalkSupertypes(
+							objectType,
+							delegate(ObjectType type, int depth, bool isPrimary)
+							{
+								ObjectTypeVisitorResult result = ObjectTypeVisitorResult.Continue;
+								if (isPrimary)
+								{
+									if (IsElementExcluded(type))
+									{
+										result = ObjectTypeVisitorResult.Stop;
+									}
+									else if (type.PreferredIdentifier != null)
+									{
+										preferridentifierFrom = type;
+										result = ObjectTypeVisitorResult.Stop;
+									}
+									else
+									{
+										result = ObjectTypeVisitorResult.SkipFollowingSiblings; // We already have the primary, no need to look further at this level
+									}
+								}
+								else if (depth != 0)
+								{
+									result = ObjectTypeVisitorResult.SkipChildren;
+								}
+								return result;
+							});
+						return preferridentifierFrom != null;
+					}
 					return true;
 				}
 				return false;
@@ -275,6 +309,8 @@
 						{
 							exclusionLink.Delete();
 							AddObjectType(objectType);
+
+							// Consider readding associated fact types
 							foreach (Role playedRole in objectType.PlayedRoleCollection)
 							{
 								FactType factType = playedRole.FactType;
@@ -292,6 +328,33 @@
 									}
 								}
 							}
+
+							// Consider readding subtypes excluded because this element was excluded
+							if (!objectType.IsValueType)
+							{
+								// Excluding an object type can leave a downstream subtype without an
+								// identifier, which excludes them. Note we only go one level deep
+								// as this will recurse naturally on the next level.
+								ObjectType.WalkSubtypes(objectType, delegate(ObjectType type, int depth, bool isPrimary)
+								{
+									switch (depth)
+									{
+										case 0:
+											return ObjectTypeVisitorResult.Continue;
+										case 1:
+											if (isPrimary)
+											{
+												if (type.PreferredIdentifier == null)
+												{
+													FilterModifiedObjectType(type);
+												}
+											}
+											return ObjectTypeVisitorResult.SkipChildren;
+										default:
+											return ObjectTypeVisitorResult.Stop;
+									}
+								});
+							}
 						}
 					}
 					else if (exclusionLink == null)
@@ -348,6 +411,9 @@
 					{
 						notifyExcluded(objectType);
 					}
+
+					// Excluding an object type leaves a FactType with a null role player,
+					// so the associated fact types also need to be excluded.
 					foreach (Role playedRole in objectType.PlayedRoleCollection)
 					{
 						ExcludeFactType(playedRole.FactType, model, false, notifyExcluded);
@@ -357,6 +423,32 @@
 							ExcludeFactType(proxy.FactType, model, false, notifyExcluded);
 						}
 					}
+
+					if (!objectType.IsValueType)
+					{
+						// Excluding an object type can leave a downstream subtype without an
+						// identifier, so exclude those as well. Note we only go one level deep
+						// as this will recurse naturally on the next level.
+						ObjectType.WalkSubtypes(objectType, delegate(ObjectType type, int depth, bool isPrimary)
+						{
+							switch (depth)
+							{
+								case 0:
+									return ObjectTypeVisitorResult.Continue;
+								case 1:
+									if (isPrimary)
+									{
+										if (type.PreferredIdentifier == null)
+										{
+											ExcludeObjectType(type, model, false, notifyExcluded);
+										}
+									}
+									return ObjectTypeVisitorResult.SkipChildren;
+								default:
+									return ObjectTypeVisitorResult.Stop;
+							}
+						});
+					}
 				}
 			}
 			#endregion // Exclude* methods, exclude elements from absorption consideration
@@ -575,6 +667,27 @@
 				}
 			}
 			#endregion // Model error tracking rules
+			#region Preferred Identifier Tracking Rules
+			/// <summary>
+			/// AddRule: typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier)
+			/// Handle cases where subtypes have no preferred identifier. Note that this
+			/// is not necessarily an error condition in the core model, so we will not always
+			/// an error deleting notification on this object type, but this condition blocks
+			/// absorption on directly and indirectly subtyped objects that now need to be reconsidered.
+			/// </summary>
+			private static void PreferredIdentifierAddedRule(ElementAddedEventArgs e)
+			{
+				ObjectType objectType = ((EntityTypeHasPreferredIdentifier)e.ModelElement).PreferredIdentifierFor;
+				ObjectType.WalkSubtypes(objectType, delegate(ObjectType type, int depth, bool isPrimary)
+				{
+					if (isPrimary || depth == 0)
+					{
+						FilterModifiedObjectType(type);
+					}
+					return ObjectTypeVisitorResult.Continue;
+				});
+			}
+			#endregion // Preferred Identifier Tracking Rules
 			#region RolePlayer tracking rules
 			/// <summary>
 			/// AddRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole)
Modified: trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs	2007-09-01 19:01:35 UTC (rev 1109)
+++ trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.cs	2007-09-01 19:12:14 UTC (rev 1110)
@@ -41,6 +41,7 @@
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ORMElementGateway", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("ObjectTypeAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ORMElementGateway", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("ObjectTypeErrorAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ORMElementGateway", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("ObjectTypeErrorDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+						typeof(AbstractionModelIsForORMModel).GetNestedType("ORMElementGateway", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("PreferredIdentifierAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ORMElementGateway", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("RolePlayerAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ORMElementGateway", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("RolePlayerDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
 						typeof(AbstractionModelIsForORMModel).GetNestedType("ORMElementGateway", BindingFlags.Public | BindingFlags.NonPublic).GetNestedType("RolePlayerRolePlayerChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
@@ -90,7 +91,7 @@
 		{
 			Microsoft.VisualStudio.Modeling.RuleManager ruleManager = store.RuleManager;
 			Type[] disabledRuleTypes = ORMToORMAbstractionBridgeDomainModel.CustomDomainModelTypes;
-			for (int i = 0; i < 23; ++i)
+			for (int i = 0; i < 24; ++i)
 			{
 				ruleManager.EnableRule(disabledRuleTypes[i]);
 			}
@@ -309,6 +310,32 @@
 					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ORMElementGateway.ObjectTypeErrorDeletedRule");
 				}
 			}
+			[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier), Priority=Neumont.Tools.Modeling.FrameworkDomainModel.InlineRulePriority)]
+			private sealed class PreferredIdentifierAddedRuleClass : Microsoft.VisualStudio.Modeling.AddRule
+			{
+				[System.Diagnostics.DebuggerStepThrough()]
+				public PreferredIdentifierAddedRuleClass()
+				{
+					base.IsEnabled = false;
+				}
+				/// <summary>
+				/// Provide the following method in class: 
+				/// Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ORMElementGateway
+				/// /// <summary>
+				/// /// AddRule: typeof(Neumont.Tools.ORM.ObjectModel.EntityTypeHasPreferredIdentifier)
+				/// /// </summary>
+				/// private static void PreferredIdentifierAddedRule(ElementAddedEventArgs e)
+				/// {
+				/// }
+				/// </summary>
+				[System.Diagnostics.DebuggerStepThrough()]
+				public override void ElementAdded(Microsoft.VisualStudio.Modeling.ElementAddedEventArgs e)
+				{
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ORMElementGateway.PreferredIdentifierAddedRule");
+					ORMElementGateway.PreferredIdentifierAddedRule(e);
+					Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMToORMAbstractionBridge.AbstractionModelIsForORMModel.ORMElementGateway.PreferredIdentifierAddedRule");
+				}
+			}
 			[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), Priority=Neumont.Tools.Modeling.FrameworkDomainModel.InlineRulePriority)]
 			private sealed class RolePlayerAddedRuleClass : Microsoft.VisualStudio.Modeling.AddRule
 			{
Modified: trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml
===================================================================
--- trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml	2007-09-01 19:01:35 UTC (rev 1109)
+++ trunk/Oial/ORMOialBridge/ORMOialBridge.AttachRules.xml	2007-09-01 19:12:14 UTC (rev 1110)
@@ -48,6 +48,9 @@
 				<arg:RuleOn targetType="ObjectTypeHasObjectTypeRequiresPrimarySupertypeError" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
 				<arg:RuleOn targetType="ValueTypeHasUnspecifiedDataTypeError" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
 			</arg:DeleteRule>
+			<arg:AddRule methodName="PreferredIdentifierAddedRule">
+				<arg:RuleOn targetType="EntityTypeHasPreferredIdentifier" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
+			</arg:AddRule>
 			<arg:AddRule methodName="RolePlayerAddedRule">
 				<arg:RuleOn targetType="ObjectTypePlaysRole" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
 			</arg:AddRule>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
 |