From: <mcu...@us...> - 2007-09-12 00:10:17
|
Revision: 1125 http://orm.svn.sourceforge.net/orm/?rev=1125&view=rev Author: mcurland Date: 2007-09-11 17:10:18 -0700 (Tue, 11 Sep 2007) Log Message: ----------- More improvements to name generation, and cleans up some old stuff left over from old unique name generation. Also moves the static methods to an actual IDatabaseNameGenerator implementation. refs #338 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs Modified: trunk/RelationalModel/OialDcilBridge/NameGeneration.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-10 23:46:57 UTC (rev 1124) +++ trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-12 00:10:18 UTC (rev 1125) @@ -1,16 +1,16 @@ using System; +using System.Collections; using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; using System.Text; +using System.Text.RegularExpressions; +using Microsoft.VisualStudio.Modeling; using Neumont.Tools.ORM.ObjectModel; -using ORMCore = Neumont.Tools.ORM.ObjectModel; -using Microsoft.VisualStudio.Modeling; using Neumont.Tools.ORMAbstraction; using Neumont.Tools.ORMToORMAbstractionBridge; using Neumont.Tools.RelationalModels.ConceptualDatabase; -using System.Text.RegularExpressions; -using System.Diagnostics; -using System.Globalization; -using System.Collections; +using ORMCore = Neumont.Tools.ORM.ObjectModel; namespace Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge { @@ -49,13 +49,19 @@ string GenerateConstraintName(Constraint constraint, string longerThan); } #endregion // IDatabaseNameGenerator interface + #region ORMAbstractionToConceptualDatabaseBridgeDomainModel.NameGeneration class partial class ORMAbstractionToConceptualDatabaseBridgeDomainModel { private static class NameGeneration { #region GenerateAllNames method + private static IDatabaseNameGenerator nameGenerator; public static void GenerateAllNames(Schema schema) { + if (null == nameGenerator) + { + nameGenerator = new DefaultDatabaseNameGenerator(); + } UniqueNameGenerator uniqueChecker = new UniqueNameGenerator(); LinkedElementCollection<Table> tables = schema.TableCollection; @@ -65,7 +71,7 @@ tables, delegate(object element, string longerThan) { - return GenerateTableName((Table)element, longerThan); + return nameGenerator.GenerateTableName((Table)element, longerThan); }, delegate(object element, string longerThan) { @@ -79,7 +85,7 @@ table.ColumnCollection, delegate(object element, string longerThan) { - return GenerateColumnName((Column)element, longerThan); + return nameGenerator.GenerateColumnName((Column)element, longerThan); }, delegate(object element, string longerThan) { @@ -94,7 +100,7 @@ constraints, delegate(object element, string longerThan) { - return GenerateConstraintName((Constraint)element, longerThan); + return nameGenerator.GenerateConstraintName((Constraint)element, longerThan); }, delegate(object element, string longerThan) { @@ -397,442 +403,552 @@ #endregion // Helper methods } #endregion // Unique name generation algorithm - #region UNDONE: temporary static imitation of an IDatabaseNameGenerator implementation - private static Regex myReplaceFieldsPattern; - private static Regex myNumberPattern; - // UNDONE: This field will not remain static when this is moved - // into an object model with additional information - private static Dictionary<string, int> myCounts; - private static string GenerateTableName(Table table, string longerThan) + #region DefaultDatabaseNameGenerator class + private class DefaultDatabaseNameGenerator : IDatabaseNameGenerator { - if (null != myCounts && null == longerThan) + #region IDatabaseNameGenerator Members + string IDatabaseNameGenerator.GenerateTableName(Table table, string longerThan) { - myCounts.Clear(); + return GenerateTableName(table, longerThan); } - string singleName = null; - List<string> nameCollection = null; - AddToNameCollection(ref singleName, ref nameCollection, TableIsPrimarilyForConceptType.GetConceptType(table).Name); - return EnsureDifference(GetFinalName(singleName, nameCollection, "", CasingOption.Pascal), longerThan); - } - private static string GenerateColumnName(Column column, string longerThan) - { - // UNDONE: use these two varables to reflect preference customization - CasingOption columnCase = CasingOption.Pascal; - string columnSpace = ""; - - //the string is used when possible to avoid using the list for a single entry - string singleName = null; - List<string> nameCollection = null; - LinkedElementCollection<ConceptTypeChild> path = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column); - int pathCount = path.Count; - if (pathCount < 1) + string IDatabaseNameGenerator.GenerateColumnName(Column column, string longerThan) { - //if we dont have a path, there is nothing we can do - AddToNameCollection(ref singleName, ref nameCollection, column.Name); + return GenerateColumnName(column, longerThan); } - else + string IDatabaseNameGenerator.GenerateConstraintName(Constraint constraint, string longerThan) { - ConceptTypeChild link = null; - //this is used so that only the leaf subtype node is collected by default - bool hasSubtypeNode = false; - FactType firstFactType = null; - //find the first non subtype fact type - for (int i = 0; i < pathCount; ++i) + return GenerateConstraintName(constraint, longerThan); + } + #endregion + private static Regex myReplaceFieldsPattern; + private string GenerateTableName(Table table, string longerThan) + { + string singleName = null; + List<string> nameCollection = null; + AddToNameCollection(ref singleName, ref nameCollection, TableIsPrimarilyForConceptType.GetConceptType(table).Name); + string finalName = GetFinalName(singleName, nameCollection, "", CasingOption.Pascal); + if (NeedLongerName(finalName, longerThan)) { - link = path[i]; - LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(link); - if (factTypes.Count < 1) - { - continue; - } - firstFactType = factTypes[0]; - if (firstFactType is SubtypeFact) - { - if (!hasSubtypeNode) - { - AddToNameCollection(ref singleName, ref nameCollection, ((ConceptType)link.Target).Name); - hasSubtypeNode = true; - } - } - else - { - break; - } + return null; } + else + { + return finalName; + } + } + private string GenerateColumnName(Column column, string longerThan) + { + // UNDONE: use these two varables to reflect preference customization + CasingOption columnCase = CasingOption.Pascal; + string columnSpace = ""; - if (null == firstFactType) + //the string is used when possible to avoid using the list for a single entry + string singleName = null; + List<string> nameCollection = null; + LinkedElementCollection<ConceptTypeChild> path = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column); + int pathCount = path.Count; + if (pathCount < 1) { - //not much we can really do if there are no fact types - AddToNameCollection(ref singleName, ref nameCollection, link.Name); + //if we dont have a path, there is nothing we can do + AddToNameCollection(ref singleName, ref nameCollection, column.Name); } else { - //use the first fact type to determine if this column is part of the primary identifier - RoleBase towardsRoleBase = FactTypeMapsTowardsRole.GetTowardsRole(firstFactType); - if (IsPreferredIdentifierFactType(firstFactType, towardsRoleBase.Role)) + ConceptTypeChild link = null; + //this is used so that only the leaf subtype node is collected by default + bool hasSubtypeNode = false; + FactType mainFactType = null; + //find the first non subtype fact type + for (int i = 0; i < pathCount; ++i) { - //for primary identifiers, just use the end node value type name - AddToNameCollection(ref singleName, ref nameCollection, GetValueType(path, pathCount)); + link = path[i]; + LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(link); + if (factTypes.Count < 1) + { + continue; + } + FactType firstFactType = factTypes[0]; + if (null == mainFactType) + { + mainFactType = firstFactType; + } + if (firstFactType is SubtypeFact) + { + if (!hasSubtypeNode) + { + //add the subtype name + AddToNameCollection(ref singleName, ref nameCollection, ((ConceptType)link.Target).Name); + hasSubtypeNode = true; + } + if (mainFactType == firstFactType) + { + mainFactType = null; + } + } + if (hasSubtypeNode && null != mainFactType) + { + break; + } } + + if (null == mainFactType) + { + //not much we can really do if there are no non subtype fact types + AddToNameCollection(ref singleName, ref nameCollection, link.Name); + } else { - //search the fact type for a role name or relevant hyphen binding - LinkedElementCollection<RoleBase> factTypeRoles = firstFactType.RoleCollection; - int? unaryRoleIndex = FactType.GetUnaryRoleIndex(factTypeRoles); - bool isUnary = unaryRoleIndex.HasValue; - RoleBase oppositeRoleBase = towardsRoleBase.OppositeRoleAlwaysResolveProxy; - Role oppositeRole = oppositeRoleBase.Role; - string roleName = oppositeRole.Name; - bool usingRolePlayerName = false; - if (StringIsNullOrEmpty(roleName)) + RoleBase towardsRole = FactTypeMapsTowardsRole.GetTowardsRole(mainFactType); + Objectification objectification = mainFactType.ImpliedByObjectification; + //use the main fact type to determine if this column is part of the primary identifier + if (null == objectification && IsPreferredIdentifierFactType(mainFactType, towardsRole)) { - //no role name, look for hyphen binding - ReadingOrder readingOrder = GetReadingOrder(firstFactType, oppositeRole, isUnary); - string rolePlayerName = oppositeRole.RolePlayer.Name; - string hyphenBoundRolePlayerName; - if ((null != readingOrder) && - (IsHyphenBound(readingOrder.PrimaryReading, factTypeRoles, oppositeRoleBase, unaryRoleIndex, out hyphenBoundRolePlayerName))) + //for primary identifier columns, just use the name of the value type + AddToNameCollection(ref singleName, ref nameCollection, GetEndNodeValueType(path, pathCount)); + } + else + { + RoleBase oppositeRole = towardsRole.OppositeRole; + bool createRoleNameSecond = false; + if (null != objectification) { - //use the hyphen bound name - AddToNameCollection(ref singleName, ref nameCollection, hyphenBoundRolePlayerName); + //get the nested fact type and its towards role as they should provide more logical names + mainFactType = objectification.NestedFactType; + oppositeRole = (towardsRole.OppositeRoleAlwaysResolveProxy as RoleProxy).TargetRole; + towardsRole = oppositeRole.Role.OppositeRoleResolveProxy; + //used for second-level name precision later on, if needed + createRoleNameSecond = true; } - else + + //search the fact type for a role name or relevant hyphen binding + LinkedElementCollection<RoleBase> factTypeRoles = mainFactType.RoleCollection; + int? unaryRoleIndex = FactType.GetUnaryRoleIndex(factTypeRoles); + bool isUnary = unaryRoleIndex.HasValue; + bool createRoleName = false; + string roleName = oppositeRole.Role.Name; + if (StringIsNullOrEmpty(roleName)) { - if (isUnary) + //no role name, look for hyphen binding + ReadingOrder readingOrder = GetReadingOrder(mainFactType, towardsRole, oppositeRole, isUnary); + string hyphenBoundRolePlayerName; + if ((null != readingOrder) && + (IsHyphenBound(readingOrder.PrimaryReading, factTypeRoles, oppositeRole, unaryRoleIndex, out hyphenBoundRolePlayerName))) { - //always use predicate text for unary fact types - AddToNameCollection(ref singleName, ref nameCollection, - GetRoleNameFromPredicateText(firstFactType, firstFactType.UnaryRole, isUnary, columnSpace)); + //use the hyphen bound name + AddToNameCollection(ref singleName, ref nameCollection, hyphenBoundRolePlayerName); } else { - AddToNameCollection(ref singleName, ref nameCollection, rolePlayerName); - //used for second-level name precision later on, if needed - usingRolePlayerName = true; + if (isUnary) + { + RoleBase unaryRole = mainFactType.UnaryRole; + //always use predicate text for unary fact types + AddToNameCollection(ref singleName, ref nameCollection, + GetRoleNameFromPredicateText(mainFactType, unaryRole.OppositeRoleResolveProxy, unaryRole, isUnary, columnSpace)); + } + else + { + if (null == objectification) + { + AddToNameCollection(ref singleName, ref nameCollection, GetObjectTypeName(oppositeRole.Role.RolePlayer)); + } + //used for second-level name precision later on, if needed + createRoleName = true; + } } } - } - else - { - //use the role name - AddToNameCollection(ref singleName, ref nameCollection, roleName); - } - - //check if we need second-level name precision - if (IsEqual(singleName, nameCollection, longerThan, columnSpace)) - { - bool needValueType = true; - if (usingRolePlayerName) + else { - //generate a role name from the predicate text and prepend it - AddToNameCollection(ref singleName, ref nameCollection, - GetRoleNameFromPredicateText(firstFactType, oppositeRoleBase, isUnary, columnSpace), - 0); - //determine if we still need to append the value type name for third-level precision - needValueType = IsEqual(singleName, nameCollection, longerThan, columnSpace); + //use the role name + AddToNameCollection(ref singleName, ref nameCollection, roleName); } - if (needValueType) + + //check if we need second-level name precision + if (NeedLongerName(singleName, nameCollection, longerThan, columnSpace)) { - AddToNameCollection(ref singleName, ref nameCollection, GetValueType(path, pathCount)); + bool needValueTypeName = true; + CreateRoleName: + if (createRoleName && !createRoleNameSecond) + { + //generate a role name from the predicate text and prepend it + AddToNameCollection(ref singleName, ref nameCollection, + GetRoleNameFromPredicateText(mainFactType, towardsRole, oppositeRole, isUnary, columnSpace), + 0); + if (needValueTypeName) + { + //determine if we still need to append the value type name for third-level precision + needValueTypeName = NeedLongerName(singleName, nameCollection, longerThan, columnSpace); + } + } + if (needValueTypeName) + { + AddToNameCollection(ref singleName, ref nameCollection, GetEndNodeValueType(path, pathCount)); + + if (createRoleNameSecond && createRoleName && NeedLongerName(singleName, nameCollection, longerThan, columnSpace)) + { + //set variables so that the role name is created but not the value type again + needValueTypeName = false; + createRoleNameSecond = false; + //create the role name + goto CreateRoleName; + } + } } } } } - } - //call the final method to ensure a name difference - return EnsureDifference(GetFinalName(singleName, nameCollection, columnSpace, columnCase), longerThan); - } - private static string GenerateConstraintName(Constraint constraint, string longerThan) - { - ReferenceConstraint refConstraint = constraint as ReferenceConstraint; - if (null != refConstraint) - { - StringBuilder name = new StringBuilder(refConstraint.SourceTable.Name); - name.Append("_FK"); - return EnsureDifference(name.ToString(), longerThan); + string finalName = GetFinalName(singleName, nameCollection, columnSpace, columnCase); + if (NeedLongerName(finalName, longerThan)) + { + //no more precision available + return null; + } + else + { + return finalName; + } } - return constraint.Name; - } - private static void AddToNameCollection(ref string singleName, ref List<string> nameCollection, string newName) - { - Debug.Assert(!StringIsNullOrEmpty(newName)); - AddToNameCollection(ref singleName, ref nameCollection, newName, -1); - } - private static void AddToNameCollection(ref string singleName, ref List<string> nameCollection, string newName, int index) - { - newName = newName.Trim(); - if (newName.Contains(" ")) + private string GenerateConstraintName(Constraint constraint, string longerThan) { - string[] individualEntries = newName.Split(' '); - for (int i = 0; i < individualEntries.Length; ++i) + ReferenceConstraint refConstraint = constraint as ReferenceConstraint; + if (null != refConstraint) { - //add each space separated name individually - AddToNameCollection(ref singleName, ref nameCollection, individualEntries[i], index == -1 ? -1 : index + i); + string name = refConstraint.SourceTable.Name + "_FK"; + if (NeedLongerName(name, longerThan)) + { + return null; + } + else + { + return name; + } } - return; + return constraint.Name; } - - if (null == singleName) + private void AddToNameCollection(ref string singleName, ref List<string> nameCollection, string newName) { - //we only have one name so far, so just use the string - singleName = newName; + AddToNameCollection(ref singleName, ref nameCollection, newName, -1); } - else + private void AddToNameCollection(ref string singleName, ref List<string> nameCollection, string newName, int index) { - //we need to now use the collection - if (null == nameCollection) + newName = newName.Trim(); + Debug.Assert(!string.IsNullOrEmpty(newName)); + if (newName.Contains(" ")) { - nameCollection = new List<string>(); - //first add to the actual collection the element that had previosly been added - nameCollection.Add(singleName); + string[] individualEntries = newName.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + for (int i = 0; i < individualEntries.Length; ++i) + { + //add each space separated name individually + AddToNameCollection(ref singleName, ref nameCollection, individualEntries[i], index == -1 ? -1 : index + i); + } + return; } - if (index == -1) + + if (null == singleName) { - nameCollection.Add(newName); + //we only have one name so far, so just use the string + singleName = newName; } else { - nameCollection.Insert(index, newName); + //we need to now use the collection + if (null == nameCollection) + { + nameCollection = new List<string>(); + //first add to the actual collection the element that had previosly been added + nameCollection.Add(singleName); + } + int count; + if (index == -1) + { + index = nameCollection.Count; + count = index + 1; + nameCollection.Add(newName); + } + else + { + nameCollection.Insert(index, newName); + count = nameCollection.Count; + } + //remove duplicate information + int nextIndex; + if ((index > 0 && nameCollection[index - 1].EndsWith(newName, StringComparison.CurrentCultureIgnoreCase)) + || ((nextIndex = index + 1) < count && nameCollection[nextIndex].StartsWith(newName, StringComparison.CurrentCultureIgnoreCase))) + { + //we don't need the name that was just added + nameCollection.RemoveAt(index); + } + else + { + //check if we need the following name + while (nextIndex < count) + { + if (newName.EndsWith(nameCollection[nextIndex], StringComparison.CurrentCultureIgnoreCase)) + { + nameCollection.RemoveAt(nextIndex); + --count; + } + else + { + break; + } + } + //check the preceding name + nextIndex = index - 1; + while (nextIndex > -1) + { + if (newName.StartsWith(nameCollection[nextIndex], StringComparison.CurrentCultureIgnoreCase)) + { + nameCollection.RemoveAt(nextIndex--); + } + else + { + break; + } + } + } } } - } - private static bool IsEqual(string finalName, List<string> finalNameCollection, string longerThan, string space) - { - return (null != longerThan) && - longerThan.StartsWith(GetFinalName(finalName, finalNameCollection, space), StringComparison.CurrentCultureIgnoreCase); - } - private static string GetFinalName(string singleName, List<string> nameCollection, string space) - { - //use -1 to signify that case changes should not be done - return GetFinalName(singleName, nameCollection, space, CasingOption.None); - } - private static string GetFinalName(string singleName, List<string> nameCollection, string space, CasingOption casing) - { - string finalName; - if (null == nameCollection) + private bool NeedLongerName(string finalName, List<string> finalNameCollection, string longerThan, string space) { - if (casing == CasingOption.None) - { - finalName = singleName; - } - else - { - finalName = DoFirstWordCasing(singleName, casing); - } + return NeedLongerName(GetFinalName(finalName, finalNameCollection, space), longerThan); } - else + private bool NeedLongerName(string finalName, string longerThan) { - string name; - if (casing == CasingOption.None) + return finalName == "" || ((null != longerThan) && longerThan.IndexOf(finalName, 0, StringComparison.CurrentCultureIgnoreCase) > -1); + } + private string GetFinalName(string singleName, List<string> nameCollection, string space) + { + //use -1 to signify that case changes should not be done + return GetFinalName(singleName, nameCollection, space, CasingOption.None); + } + private string GetFinalName(string singleName, List<string> nameCollection, string space, CasingOption casing) + { + string finalName; + if (null == nameCollection) { - name = nameCollection[0]; + if (null == singleName) + { + return ""; + } + else if (casing == CasingOption.None) + { + finalName = singleName; + } + else + { + finalName = DoFirstWordCasing(singleName, casing, CultureInfo.CurrentCulture.TextInfo); + } } else { - name = DoFirstWordCasing(nameCollection[0], casing); - } + TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo; - //we already know there are at least two name entries, so use a string builder - StringBuilder builder = new StringBuilder(name); - - //we already have the first entry, so mark camel as pascal - CasingOption tempCasing = casing; - if (tempCasing == CasingOption.Camel) - { - tempCasing = CasingOption.Pascal; - } - - int count = nameCollection.Count; - for (int i = 1; i < count; ++i) - { - builder.Append(space); + string name; if (casing == CasingOption.None) { - name = nameCollection[i]; + name = nameCollection[0]; } else { - name = DoFirstWordCasing(nameCollection[i], tempCasing); + name = DoFirstWordCasing(nameCollection[0], casing, textInfo); } - builder.Append(name); + + //we already know there are at least two name entries, so use a string builder + StringBuilder builder = new StringBuilder(name); + + //we already have the first entry, so mark camel as pascal + CasingOption tempCasing = casing; + if (tempCasing == CasingOption.Camel) + { + tempCasing = CasingOption.Pascal; + } + + //add each entry with proper spaces and casing + int count = nameCollection.Count; + for (int i = 1; i < count; ++i) + { + builder.Append(space); + if (casing == CasingOption.None) + { + name = nameCollection[i]; + } + else + { + name = DoFirstWordCasing(nameCollection[i], tempCasing, textInfo); + } + builder.Append(name); + } + finalName = builder.ToString(); } - finalName = builder.ToString(); + + return finalName; } - - return finalName; - } - private static string DoFirstWordCasing(string name, CasingOption casing) - { - switch (casing) + private string DoFirstWordCasing(string name, CasingOption casing, TextInfo textInfo) { - case CasingOption.Camel: - return DoFirstLetterCase(name, false); - case CasingOption.Pascal: - return DoFirstLetterCase(name, true); - case CasingOption.Flat: - return CultureInfo.CurrentCulture.TextInfo.ToLower(name); - case CasingOption.Upper: - return CultureInfo.CurrentCulture.TextInfo.ToUpper(name); - } + switch (casing) + { + case CasingOption.Camel: + return DoFirstLetterCase(name, false, textInfo); + case CasingOption.Pascal: + return DoFirstLetterCase(name, true, textInfo); + case CasingOption.Flat: + return textInfo.ToLower(name); + case CasingOption.Upper: + return textInfo.ToUpper(name); + } - return null; - } - private static string DoFirstLetterCase(string name, bool upper) - { - char c = name[0]; - if (upper) - { - c = CultureInfo.CurrentCulture.TextInfo.ToUpper(c); + return null; } - else + private string DoFirstLetterCase(string name, bool upper, TextInfo textInfo) { - c = CultureInfo.CurrentCulture.TextInfo.ToLower(c); + char c = name[0]; + if (upper) + { + c = textInfo.ToUpper(c); + } + else + { + c = textInfo.ToLower(c); + } + if (name.Length > 1) + { + name = c.ToString() + name.Substring(1); + } + else + { + name = c.ToString(); + } + return name; } - if (name.Length > 1) + private bool IsHyphenBound(IReading reading, LinkedElementCollection<RoleBase> factTypeRoles, RoleBase role, int? unaryRoleIndex, out string hyphenBoundRolePlayerName) { - name = c.ToString() + name.Substring(1); + // UNDONE: The hyphen binder does a lot of stuff we don't need, including + // building replacement strings for each role and rebuilding the predicate text. + // Add another method to the hyphenBinder to support binding one role only. + VerbalizationHyphenBinder hyphenBinder = new VerbalizationHyphenBinder(reading, factTypeRoles, unaryRoleIndex, "{0}{{0}}{1}"); + string rolePlayerName = role.Role.RolePlayer.Name; + hyphenBoundRolePlayerName = hyphenBinder.HyphenBindRoleReplacement(rolePlayerName, factTypeRoles.IndexOf(role)); + return ((object)hyphenBoundRolePlayerName != (object)rolePlayerName); } - else + private bool IsPreferredIdentifierFactType(FactType factType, RoleBase role) { - name = c.ToString(); - } - return name; - } - private static bool IsHyphenBound(IReading reading, LinkedElementCollection<RoleBase> factTypeRoles, RoleBase role, int? unaryRoleIndex, out string hyphenBoundRolePlayerName) - { - // UNDONE: The hyphen binder does a lot of stuff we don't need, including - // building replacement strings for each role and rebuilding the predicate text. - // Add another method to the hyphenBinder to support binding one role only. - VerbalizationHyphenBinder hyphenBinder = new VerbalizationHyphenBinder(reading, factTypeRoles, unaryRoleIndex, "{0}{{0}}{1}"); - string rolePlayerName = role.Role.RolePlayer.Name; - hyphenBoundRolePlayerName = hyphenBinder.HyphenBindRoleReplacement(rolePlayerName, factTypeRoles.IndexOf(role)); - return ((object)hyphenBoundRolePlayerName != (object)rolePlayerName); - } - private static bool IsPreferredIdentifierFactType(FactType factType, Role role) - { - return role.RolePlayer.ResolvedPreferredIdentifier.FactTypeCollection.Contains(factType); - } - private static string GetValueType(LinkedElementCollection<ConceptTypeChild> path, int pathCount) - { - //find the last ConceptTypeChild with an InformationTypeFormat target - for (int i = pathCount; --i > -1; ) - { - ConceptTypeChild link = path[i]; - InformationTypeFormat target; - if (null != (target = link.Target as InformationTypeFormat)) + ORMCore.UniquenessConstraint preferredIdentifier = role.Role.RolePlayer.ResolvedPreferredIdentifier; + if (null == preferredIdentifier) { - LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(link); - ObjectType objectType = FactTypeMapsTowardsRole.GetTowardsRole(factTypes[factTypes.Count - 1]).Role.RolePlayer; - ObjectType valueType; - string name = ReferenceModeNaming.ResolveObjectTypeName(objectType, - valueType = InformationTypeFormatIsForValueType.GetValueType(target)); - return name ?? valueType.Name; + return false; } + return preferredIdentifier.FactTypeCollection.Contains(factType); } - return null; - } - private static string GetRoleNameFromPredicateText(FactType factType, RoleBase role, bool isUnary, string spaceReplaceString) - { - ReadingOrder readingOrder = GetReadingOrder(factType, role.Role, isUnary); - if (null == readingOrder) + private string GetObjectTypeName(ObjectType objectType) { - return role.Role.RolePlayer.Name; - } - else - { - IReading reading = readingOrder.PrimaryReading; - if (null == myReplaceFieldsPattern) + string name = ReferenceModeNaming.ResolveObjectTypeName(objectType, null); + if (StringIsNullOrEmpty(name)) { - myReplaceFieldsPattern = new Regex(@"{\d+}", RegexOptions.Compiled); + return objectType.Name; } - //get rid of string replace fields - string text = " " + myReplaceFieldsPattern.Replace(reading.Text, " ") + " "; - //remove articles - text = text.Replace(" a ", " ").Replace(" an ", " ").Replace(" the ", " "); - if (!isUnary) + else { - text = text.Replace(" has ", " "); + return name; } - return text; } - } - private static ReadingOrder GetReadingOrder(FactType factType, Role role, bool isUnary) - { - if (!isUnary) + private string GetEndNodeValueType(LinkedElementCollection<ConceptTypeChild> path, int pathCount) { - //get the reading in the correct direction, if possible - ReadingOrder readingOrder = factType.FindMatchingReadingOrder(new RoleBase[] { role.OppositeRoleAlwaysResolveProxy, role }); - if (null != readingOrder) + //find the last ConceptTypeChild with an InformationTypeFormat target + for (int i = pathCount; --i > -1; ) { - return readingOrder; + ConceptTypeChild link = path[i]; + InformationTypeFormat target; + if (null != (target = link.Target as InformationTypeFormat)) + { + return target.Name; + } } + return null; } - - //return the first reading - foreach (ReadingOrder readingOrder in factType.ReadingOrderCollection) + private string GetEndNodeObjectType(LinkedElementCollection<ConceptTypeChild> path, int pathCount) { - return readingOrder; + //find the last ConceptTypeChild with an InformationTypeFormat target + for (int i = pathCount; --i > -1; ) + { + ConceptTypeChild link = path[i]; + InformationTypeFormat target; + if (null != (target = link.Target as InformationTypeFormat)) + { + LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(link); + ObjectType objectType = FactTypeMapsTowardsRole.GetTowardsRole(factTypes[factTypes.Count - 1]).Role.RolePlayer; + if (null != objectType.NestedFactType) + { + return GetEndNodeValueType(path, pathCount); + } + return GetObjectTypeName(objectType); + } + } + return null; } - - return null; - } - private static string EnsureDifference(string name, string longerThan) - { - if (null != longerThan && longerThan.StartsWith(name)) + private string GetRoleNameFromPredicateText(FactType factType, RoleBase towardsRole, RoleBase oppositeRole, bool isUnary, string spaceReplaceString) { - bool areEqual = name == longerThan; - if (!areEqual) + ReadingOrder readingOrder = GetReadingOrder(factType, towardsRole, oppositeRole, isUnary); + if (null != readingOrder) { - //determine if longerThan is just name followed by a string of numbers - if (null == myNumberPattern) + IReading reading = readingOrder.PrimaryReading; + if (null == myReplaceFieldsPattern) { - myNumberPattern = new Regex(@"\d+", RegexOptions.RightToLeft | RegexOptions.Compiled); + myReplaceFieldsPattern = new Regex(@"{\d+}", RegexOptions.Compiled); } - string endNumbers = longerThan.Substring(name.Length); - Match longerThanMatches = myNumberPattern.Match(endNumbers); - if (longerThanMatches.Success && longerThanMatches.Index + longerThanMatches.Length == endNumbers.Length) + //get rid of string replace fields + string text = myReplaceFieldsPattern.Replace(reading.Text, " "); + text = " " + CultureInfo.CurrentCulture.TextInfo.ToLower(text) + " "; + //remove articles + text = text.Replace(" a ", " ").Replace(" an ", " ").Replace(" the ", " "); + if (!isUnary && text.Trim() != "has") { - //if so, mark them as equal - areEqual = true; + text = text.Replace(" has ", " "); } + if (!StringIsNullOrEmpty(text)) + { + return text; + } } - if (areEqual) + return GetObjectTypeName(oppositeRole.Role.RolePlayer); + } + private ReadingOrder GetReadingOrder(FactType factType, RoleBase towardsRole, RoleBase oppositeRole, bool isUnary) + { + if (!isUnary) { - if (null == myCounts) + //get the reading in the correct direction, if possible + ReadingOrder readingOrder = factType.FindMatchingReadingOrder(new RoleBase[] { towardsRole, oppositeRole }); + if (null != readingOrder) { - myCounts = new Dictionary<string, int>(); + return readingOrder; } - int curCount; - if (myCounts.ContainsKey(name)) - { - //keep track of the number of occurances of this string - curCount = ++myCounts[name]; - } - else - { - curCount = 1; - myCounts.Add(name, 1); - } - name += curCount.ToString(); } + + //return the first reading + foreach (ReadingOrder readingOrder in factType.ReadingOrderCollection) + { + return readingOrder; + } + + return null; } - return name; + private bool StringIsNullOrEmpty(string newName) + { + return (null == newName) || (newName.Trim().Length < 1); + } + private enum CasingOption + { + None, + Pascal, + Camel, + Flat, + Upper, + } } - private static bool StringIsNullOrEmpty(string newName) - { - return string.IsNullOrEmpty(newName.Trim()); - } - private enum CasingOption - { - None, - Pascal, - Camel, - Flat, - Upper, - } - #endregion // UNDONE: temporary static immitation of an IDatabaseNameGenerator implementation + #endregion //DefaultDatabaseNameGenerator class } } + #endregion //ORMAbstractionToConceptualDatabaseBridgeDomainModel.NameGeneration class } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |