|
From: <mcu...@us...> - 2009-03-20 23:39:12
|
Revision: 1372
http://orm.svn.sourceforge.net/orm/?rev=1372&view=rev
Author: mcurland
Date: 2009-03-20 23:38:59 +0000 (Fri, 20 Mar 2009)
Log Message:
-----------
Handle cyclic deep mapping scenario with collapsed tables across a unary objectification pattern. Also trigger absorption regeneration on mandatory and uniqueness changes on an objectified FactType by validating the associated binarized FactType, not the objectified FactType. refs #327
Modified Paths:
--------------
trunk/Oial/ORMOialBridge/ModificationTracker.cs
trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs
Modified: trunk/Oial/ORMOialBridge/ModificationTracker.cs
===================================================================
--- trunk/Oial/ORMOialBridge/ModificationTracker.cs 2009-03-18 00:22:10 UTC (rev 1371)
+++ trunk/Oial/ORMOialBridge/ModificationTracker.cs 2009-03-20 23:38:59 UTC (rev 1372)
@@ -43,7 +43,7 @@
{
if (IsRelevantConstraint(constraint))
{
- FactTypeConstraintPatternChanged(link.Role.FactType);
+ FactTypeConstraintPatternChanged(link.Role.BinarizedFactType);
}
switch (constraint.ConstraintType)
{
@@ -67,7 +67,7 @@
{
if (IsRelevantConstraint(constraint))
{
- FactTypeConstraintPatternChanged(link.Role.FactType);
+ FactTypeConstraintPatternChanged(link.Role.BinarizedFactType);
}
switch (constraint.ConstraintType)
{
@@ -116,9 +116,12 @@
SetConstraint constraint = (SetConstraint)e.ModelElement;
if (IsRelevantConstraint(constraint.Constraint))
{
- foreach (FactType factType in constraint.FactTypeCollection)
+ foreach (Role role in constraint.RoleCollection)
{
- FactTypeConstraintPatternChanged(factType);
+ // Note that constraint.FactTypeCollection does not resolve the
+ // BinarizedFactType. Notifying twice on one FactType is harmless
+ // due to delayed validation.
+ FactTypeConstraintPatternChanged(role.BinarizedFactType);
}
}
}
@@ -240,14 +243,14 @@
ObjectTypePlaysRole link = (ObjectTypePlaysRole)e.ElementLink;
if (e.DomainRole.Id == ObjectTypePlaysRole.PlayedRoleDomainRoleId)
{
- SignificantFactTypeChange(((Role)e.OldRolePlayer).FactType);
+ SignificantFactTypeChange(((Role)e.OldRolePlayer).BinarizedFactType);
}
else
{
SignificantObjectTypeChange((ObjectType)e.OldRolePlayer);
}
SignificantObjectTypeChange(link.RolePlayer);
- SignificantFactTypeChange(link.PlayedRole.FactType);
+ SignificantFactTypeChange(link.PlayedRole.BinarizedFactType);
}
#endregion // ORM modification rule methods
#region Bridge deletion rule methods
Modified: trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs
===================================================================
--- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2009-03-18 00:22:10 UTC (rev 1371)
+++ trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2009-03-20 23:38:59 UTC (rev 1372)
@@ -867,6 +867,7 @@
foreach (ConceptType conceptType in this.AbstractionModel.ConceptTypeCollection)
{
ObjectType objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType);
+ bool? conceptTypeHasDeepMappingAway = null;
// NOTE: We don't need the ShouldIgnoreObjectType filter here, because object
// types that we want to ignore won't be in the OIAL model in the first place.
@@ -884,7 +885,7 @@
{
// The fact type has a mapping and that mapping is towards the role played by
// this concept type, so we need to generate concept type children for it.
- GenerateConceptTypeChildrenForFactTypeMapping(factTypeMappings, conceptType, factTypeMapping, factTypePath, true);
+ GenerateConceptTypeChildrenForFactTypeMapping(factTypeMappings, conceptType, ref conceptTypeHasDeepMappingAway, factTypeMapping, factTypePath, true);
}
}
}
@@ -900,6 +901,10 @@
/// <param name="parentConceptType">
/// The <see cref="ConceptType"/> into which <see cref="ConceptTypeChild">concept type children</see> should be generated.
/// </param>
+ /// <param name="parentConceptTypeHasDeepAway">
+ /// Test if the parent concept type has a deep mapping away from it. Handles some cyclic cases by making a potential assimilation
+ /// into a reference. Delay calculated because this is not always needed.
+ /// </param>
/// <param name="factTypeMapping">
/// The <see cref="FactTypeMapping"/> for which <see cref="ConceptTypeChild">concept type children</see> should be generated.
/// </param>
@@ -909,7 +914,7 @@
/// <param name="isMandatorySoFar">
/// Indicates whether every step in <paramref name="factTypePath"/> is mandatory for the parent concept type (towards object type).
/// </param>
- private static void GenerateConceptTypeChildrenForFactTypeMapping(FactTypeMappingDictionary factTypeMappings, ConceptType parentConceptType, FactTypeMapping factTypeMapping, List<FactType> factTypePath, bool isMandatorySoFar)
+ private static void GenerateConceptTypeChildrenForFactTypeMapping(FactTypeMappingDictionary factTypeMappings, ConceptType parentConceptType, ref bool? parentConceptTypeHasDeepAway, FactTypeMapping factTypeMapping, List<FactType> factTypePath, bool isMandatorySoFar)
{
// Push the current fact type onto the path.
factTypePath.Add(factTypeMapping.FactType);
@@ -1080,8 +1085,46 @@
// UNDONE: Would we ever want to use a depth other than shallow here? Probably not, but it might be worth looking in to.
preferredIdentifierFactTypeMapping = new FactTypeMapping(preferredIdentifierFactType, preferredIdentifierFactTypeMapping.TowardsRole, preferredIdentifierFactTypeMapping.FromRole, MappingDepth.Shallow);
}
+ else if (preferredIdentifierFactTypeMapping.MappingDepth == MappingDepth.Deep)
+ {
+ // Handle cyclic deep mapping scenario with collapsed entities.
+ // The primary scenario here is:
+ // 1) B is a subtype of A and identified by A's identifier
+ // 2) A and B participate in an objectified 1-1 FactType
+ // 3) The uniqueness constraint on the A role is the preferred identifier
+ // 4) The A role is mandatory
+ // In this case, without this code, you get an assimilation mapping B into A
+ // and mapping A into B. We fix this case by forwarding a shallow mapping,
+ // which generates a reference instad of an assimilation.
+ if (!parentConceptTypeHasDeepAway.HasValue)
+ {
+ ObjectType objectType = ConceptTypeIsForObjectType.GetObjectType(parentConceptType);
+ foreach (Role role in ConceptTypeIsForObjectType.GetObjectType(parentConceptType).PlayedRoleCollection)
+ {
+ FactType factType;
+ FactTypeMapping testMapping;
+ if (null != (factType = role.BinarizedFactType) &&
+ factTypeMappings.TryGetValue(factType, out testMapping) &&
+ testMapping.MappingDepth == MappingDepth.Deep &&
+ testMapping.FromObjectType == objectType)
+ {
+ preferredIdentifierFactTypeMapping = new FactTypeMapping(preferredIdentifierFactType, preferredIdentifierFactTypeMapping.FromRole, preferredIdentifierFactTypeMapping.TowardsRole, MappingDepth.Shallow);
+ parentConceptTypeHasDeepAway = true;
+ break;
+ }
+ }
+ if (!parentConceptTypeHasDeepAway.HasValue)
+ {
+ parentConceptTypeHasDeepAway = false;
+ }
+ }
+ else if (parentConceptTypeHasDeepAway.Value)
+ {
+ preferredIdentifierFactTypeMapping = new FactTypeMapping(preferredIdentifierFactType, preferredIdentifierFactTypeMapping.FromRole, preferredIdentifierFactTypeMapping.TowardsRole, MappingDepth.Shallow);
+ }
+ }
- GenerateConceptTypeChildrenForFactTypeMapping(factTypeMappings, parentConceptType, preferredIdentifierFactTypeMapping, factTypePath, isMandatory);
+ GenerateConceptTypeChildrenForFactTypeMapping(factTypeMappings, parentConceptType, ref parentConceptTypeHasDeepAway, preferredIdentifierFactTypeMapping, factTypePath, isMandatory);
}
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|