|
From: <mcu...@us...> - 2014-12-02 22:16:56
|
Revision: 1553
http://sourceforge.net/p/orm/code/1553
Author: mcurland
Date: 2014-12-02 22:16:48 +0000 (Tue, 02 Dec 2014)
Log Message:
-----------
Cross-model constraint merging matched constraints that restricted the same roles irrespective of the join paths. However, separate join paths can lead to much different constraints, so this should be a primary requirement for matching, not a secondary consideration.
Modified Paths:
--------------
trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs
Modified: trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs
===================================================================
--- trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs 2014-12-02 05:50:51 UTC (rev 1552)
+++ trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs 2014-12-02 22:16:48 UTC (rev 1553)
@@ -1780,7 +1780,8 @@
break;
}
}
- if (i == roleCount)
+ if (i == roleCount &&
+ LeadRolePath.VerifyJoinPathMatch(this, testOtherSetConstraint, foreignStore, elementTracker))
{
// We have a match
if (testOtherSetConstraint.Modality == matchConstraintModality)
@@ -1884,11 +1885,10 @@
// Now find matching sequences for each role
bool matchSequenceOrder = 0 != (constraint.RoleSequenceStyles & RoleSequenceStyles.OrderedRoleSequences);
- otherMatchingRoles = allOtherMatchingRoles[0]; // Match the first sequence first
- roleCount = otherMatchingRoles.Length;
- Role firstMatchingRole = otherMatchingRoles[0];
+ Role firstMatchingRole = allOtherMatchingRoles[0][0];
foreach (ConstraintRoleSequence sequence in firstMatchingRole.ConstraintRoleSequenceCollection)
{
+ roleCount = (otherMatchingRoles = allOtherMatchingRoles[0]).Length; // Match the first sequence first
SetComparisonConstraintRoleSequence testOtherSequence;
SetComparisonConstraint testOtherConstraint;
LinkedElementCollection<SetComparisonConstraintRoleSequence> testOtherSequences;
@@ -1976,20 +1976,36 @@
if (trailingSequenceIndex == sequenceCount)
{
- // We have a full constraint match on all sequences.
- if (testOtherConstraint.Modality == matchConstraintModality)
+ // Sequence roles all match up. Make sure that the join paths are
+ // also a match before declaring success. It is possible to have constraints
+ // over the same roles with different join paths. Note that an overabundance
+ // of caution here will simply result in constraints over the same roles, which
+ // will result in validation errors displayed to the user.
+ i = 0;
+ for (; i < sequenceCount; ++i)
{
- otherSetComparisonConstraint = testOtherConstraint;
- otherSetComparisonSequences = testOtherSequences;
- break; // We won't find a better match
+ if (!LeadRolePath.VerifyJoinPathMatch(sequences[matchedOtherSequences[i] - 1], testOtherSequences[i], foreignStore, elementTracker))
+ {
+ break;
+ }
}
- else if (otherSetComparisonConstraintMismatchedModality == null)
+ if (i == sequenceCount)
{
- otherSetComparisonConstraintMismatchedModality = testOtherConstraint;
- otherSetComparisonSequencesMismatchedModality = testOtherSequences;
- matchedOtherSequencesMismatchedModality = matchedOtherSequences;
- matchedOtherSequences = null;
- // Do not break, try to find a full modality match
+ // We have a full constraint match on all sequences.
+ if (testOtherConstraint.Modality == matchConstraintModality)
+ {
+ otherSetComparisonConstraint = testOtherConstraint;
+ otherSetComparisonSequences = testOtherSequences;
+ break; // We won't find a better match
+ }
+ else if (otherSetComparisonConstraintMismatchedModality == null)
+ {
+ otherSetComparisonConstraintMismatchedModality = testOtherConstraint;
+ otherSetComparisonSequencesMismatchedModality = testOtherSequences;
+ matchedOtherSequencesMismatchedModality = matchedOtherSequences;
+ matchedOtherSequences = null;
+ // Do not break, try to find a full modality match
+ }
}
}
}
@@ -2381,6 +2397,76 @@
return null;
}
/// <summary>
+ /// Helper function to verify matching paths during import.
+ /// </summary>
+ /// <param name="paths">The paths to check against.</param>
+ /// <param name="otherPaths">The paths to search.</param>
+ /// <param name="foreignStore">The store being copied from.</param>
+ /// <param name="elementTracker">The element tracker determining which elements are imported.</param>
+ /// <returns><see langword="true"/> if all paths have a match.</returns>
+ private static bool VerifyMatchingPaths(IList<LeadRolePath> paths, IList<LeadRolePath> otherPaths, Store foreignStore, IEquivalentElementTracker elementTracker)
+ {
+ int pathCount = paths.Count;
+ if (pathCount == 0)
+ {
+ return otherPaths.Count == 0;
+ }
+ else if (otherPaths.Count != pathCount)
+ {
+ return false;
+ }
+ if (pathCount != 1)
+ {
+ // Copy to writable collection so we can remove when processed.
+ LeadRolePath[] otherPathsArray = new LeadRolePath[pathCount];
+ otherPaths.CopyTo(otherPathsArray, 0);
+ otherPaths = otherPathsArray;
+ }
+ Dictionary<ModelElement, ModelElement> matchedPathElements = new Dictionary<ModelElement, ModelElement>();
+ for (int i = 0; i < pathCount; ++i)
+ {
+ LeadRolePath matchingPath;
+ if (null != (matchingPath = paths[i].GetMatchingPath(otherPaths, matchedPathElements, foreignStore, elementTracker)))
+ {
+ if (pathCount != 1)
+ {
+ otherPaths.Remove(matchingPath);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ /// <summary>
+ /// Helper to determine if join paths match for role sequences.
+ /// </summary>
+ /// <param name="roleSequence">The role sequence from the current store.</param>
+ /// <param name="otherRoleSequence">The role sequence from the foreign store.</param>
+ /// <param name="foreignStore">The store being copied from.</param>
+ /// <param name="elementTracker">The element tracker determining which elements are imported.</param>
+ /// <returns><see langword="true"/> if the join paths are equivalent.</returns>
+ public static bool VerifyJoinPathMatch(ConstraintRoleSequence roleSequence, ConstraintRoleSequence otherRoleSequence, Store foreignStore, IEquivalentElementTracker elementTracker)
+ {
+ ConstraintRoleSequenceJoinPath sequenceJoinPath;
+ if (null != (sequenceJoinPath = roleSequence.JoinPath))
+ {
+ ConstraintRoleSequenceJoinPath otherSequenceJoinPath;
+ if (null == (otherSequenceJoinPath = otherRoleSequence.JoinPath) ||
+ !LeadRolePath.VerifyMatchingPaths(sequenceJoinPath.LeadRolePathCollection, otherSequenceJoinPath.LeadRolePathCollection, foreignStore, elementTracker))
+ {
+ return false;
+ }
+ }
+ else if (otherRoleSequence.JoinPath != null)
+ {
+ return false;
+ }
+ return true;
+ }
+ /// <summary>
/// Implements <see cref="IElementEquivalence.MapEquivalentElements"/>
/// Match paths by roots, pathed roles, and conditional calculations.
/// </summary>
@@ -2627,7 +2713,7 @@
PathedRole otherPathedRole = otherPathedRoles[i];
if (pathedRole.PathedRolePurpose != otherPathedRole.PathedRolePurpose ||
pathedRole.IsNegated != otherPathedRole.IsNegated ||
- null == CopyMergeUtility.GetEquivalentElement(pathedRole.Role, foreignStore, elementTracker))
+ otherPathedRole.Role != CopyMergeUtility.GetEquivalentElement(pathedRole.Role, foreignStore, elementTracker))
{
return false;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|