|
From: <mcu...@us...> - 2007-08-30 17:22:09
|
Revision: 1100
http://orm.svn.sourceforge.net/orm/?rev=1100&view=rev
Author: mcurland
Date: 2007-08-30 10:21:57 -0700 (Thu, 30 Aug 2007)
Log Message:
-----------
Provides a basic and intelligent relational schema name generation algorithm, and reruns the algorithm on name changes to the conceptual model. Includes a minor name and access change on FactType. refs #334
Modified Paths:
--------------
trunk/ORMModel/ObjectModel/FactType.cs
trunk/ORMModel/Shell/ReadingEditor.cs
trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs
trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.cs
trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.xml
trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs
trunk/RelationalModel/OialDcilBridge/OialDcilBridge.csproj
Added Paths:
-----------
trunk/RelationalModel/OialDcilBridge/NameGeneration.cs
Modified: trunk/ORMModel/ObjectModel/FactType.cs
===================================================================
--- trunk/ORMModel/ObjectModel/FactType.cs 2007-08-30 17:19:27 UTC (rev 1099)
+++ trunk/ORMModel/ObjectModel/FactType.cs 2007-08-30 17:21:57 UTC (rev 1100)
@@ -66,7 +66,7 @@
/// it will then create a new ReadingOrder. It operates under the assumption
/// that a transaction has already been started.
/// </summary>
- public ReadingOrder GetReadingOrder(IList<RoleBase> roleOrder)
+ public ReadingOrder EnsureReadingOrder(IList<RoleBase> roleOrder)
{
ReadingOrder retVal = FindMatchingReadingOrder(roleOrder);
if (retVal == null)
@@ -118,7 +118,7 @@
/// the assumption that a transaction has already been started.
/// </summary>
/// <returns>Should always return a value unless there was an error creating the ReadingOrder</returns>
- public ReadingOrder CreateReadingOrder(IList<RoleBase> roleOrder)
+ private ReadingOrder CreateReadingOrder(IList<RoleBase> roleOrder)
{
ReadingOrder retval = null;
if (roleOrder.Count > 0)
Modified: trunk/ORMModel/Shell/ReadingEditor.cs
===================================================================
--- trunk/ORMModel/Shell/ReadingEditor.cs 2007-08-30 17:19:27 UTC (rev 1099)
+++ trunk/ORMModel/Shell/ReadingEditor.cs 2007-08-30 17:21:57 UTC (rev 1100)
@@ -1695,7 +1695,7 @@
myInsertedRow = row;
using (Transaction t = store.TransactionManager.BeginTransaction(ResourceStrings.ModelReadingEditorNewReadingTransactionText))
{
- ReadingOrder theOrder = myFact.GetReadingOrder(myReadingOrderKeyedCollection[row].RoleOrder);
+ ReadingOrder theOrder = myFact.EnsureReadingOrder(myReadingOrderKeyedCollection[row].RoleOrder);
Debug.Assert(theOrder != null, "A ReadingOrder should have been found or created.");
theNewReading = new Reading(store);
LinkedElementCollection<Reading> readings = theOrder.ReadingCollection;
@@ -2560,7 +2560,7 @@
{
if (myReadingOrder == null) //obtain new readingOrder to commit a new reading (in readingOrder is non-existent)
{
- myReadingOrder = myParentBranch.Fact.GetReadingOrder(this.myRoleOrder);
+ myReadingOrder = myParentBranch.Fact.EnsureReadingOrder(this.myRoleOrder);
}
myReadingBranch = new ReadingBranch(myParentBranch.Fact, myReadingOrder, this);
return myReadingBranch;
Modified: trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs
===================================================================
--- trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs 2007-08-30 17:19:27 UTC (rev 1099)
+++ trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs 2007-08-30 17:21:57 UTC (rev 1100)
@@ -180,6 +180,98 @@
}
}
#endregion // Bridge element modification rules
+ #region Name modification rules
+ /// <summary>
+ /// ChangeRule: typeof(Neumont.Tools.ORMAbstraction.ConceptType)
+ /// </summary>
+ private static void ConceptTypeChangedRule(ElementPropertyChangedEventArgs e)
+ {
+ if (e.DomainProperty.Id == ConceptType.NameDomainPropertyId)
+ {
+ ValidateTableNameChanged(TableIsPrimarilyForConceptType.GetTable((ConceptType)e.ModelElement));
+ }
+ }
+ /// <summary>
+ /// ChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.FactType)
+ /// </summary>
+ private static void FactTypeNameChangedRule(ElementPropertyChangedEventArgs e)
+ {
+ if (e.DomainProperty.Id == ORMCore.FactType.NameChangedDomainPropertyId)
+ {
+ foreach (ConceptTypeChild child in ConceptTypeChildHasPathFactType.GetConceptTypeChild((ORMCore.FactType)e.ModelElement))
+ {
+ ValidateConceptTypeChildNameChanged(child);
+ }
+ }
+ }
+ /// <summary>
+ /// ChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.Role)
+ /// </summary>
+ private static void RoleNameChangedRule(ElementPropertyChangedEventArgs e)
+ {
+ if (e.DomainProperty.Id == ORMCore.Role.NameDomainPropertyId)
+ {
+ ORMCore.FactType factType = ((ORMCore.Role)e.ModelElement).FactType;
+ if (factType != null)
+ {
+ foreach (ConceptTypeChild child in ConceptTypeChildHasPathFactType.GetConceptTypeChild(factType))
+ {
+ ValidateConceptTypeChildNameChanged(child);
+ }
+ }
+ }
+ }
+ private static void ValidateConceptTypeChildNameChanged(ConceptTypeChild child)
+ {
+ if (child != null)
+ {
+ FrameworkDomainModel.DelayValidateElement(child, DelayValidateConceptTypeChildNameChanged);
+ }
+ }
+ [DelayValidatePriority(20, DomainModelType = typeof(AbstractionDomainModel), Order = DelayValidatePriorityOrder.AfterDomainModel)]
+ private static void DelayValidateConceptTypeChildNameChanged(ModelElement element)
+ {
+ if (!element.IsDeleted)
+ {
+ ConceptTypeChild child = (ConceptTypeChild)element;
+ foreach (Column column in ColumnHasConceptTypeChild.GetColumn(child))
+ {
+ ValidateSchemaNamesChanged(column.Table.Schema);
+ break;
+ }
+ }
+ }
+ private static void ValidateTableNameChanged(Table table)
+ {
+ if (table != null)
+ {
+ FrameworkDomainModel.DelayValidateElement(table, DelayValidateTableNameChanged);
+ }
+ }
+ [DelayValidatePriority(20, DomainModelType = typeof(AbstractionDomainModel), Order = DelayValidatePriorityOrder.AfterDomainModel)]
+ private static void DelayValidateTableNameChanged(ModelElement element)
+ {
+ if (!element.IsDeleted)
+ {
+ ValidateSchemaNamesChanged(((Table)element).Schema);
+ }
+ }
+ private static void ValidateSchemaNamesChanged(Schema schema)
+ {
+ if (schema != null)
+ {
+ FrameworkDomainModel.DelayValidateElement(schema, DelayValidateSchemaNamesChanged);
+ }
+ }
+ [DelayValidatePriority(30, DomainModelType = typeof(AbstractionDomainModel), Order = DelayValidatePriorityOrder.AfterDomainModel)]
+ private static void DelayValidateSchemaNamesChanged(ModelElement element)
+ {
+ if (!element.IsDeleted)
+ {
+ NameGeneration.GenerateAllNames((Schema)element);
+ }
+ }
+ #endregion // Name modification rules
}
#endregion // Regeneration rule delay validation methods
}
Added: trunk/RelationalModel/OialDcilBridge/NameGeneration.cs
===================================================================
--- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs (rev 0)
+++ trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-08-30 17:21:57 UTC (rev 1100)
@@ -0,0 +1,508 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using 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;
+
+namespace Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge
+{
+ #region IDatabaseNameGenerator interface
+ /// <summary>
+ /// Generate relational names for elements contained in a <see cref="Schema"/>
+ /// </summary>
+ public interface IDatabaseNameGenerator
+ {
+ /// <summary>
+ /// Generate a name for the provided <paramref name="table"/>
+ /// </summary>
+ /// <param name="table">A <see cref="Table"/> element</param>
+ /// <param name="longerThan">Generate a more specific name than provided.
+ /// If this is set, then the passed in name will have been generated by
+ /// this method on this instance. Can be <see langword="null"/></param>
+ /// <returns>A name for <paramref name="table"/>.</returns>
+ string GenerateTableName(Table table, string longerThan);
+ /// <summary>
+ /// Generate a name for the provided <paramref name="column"/>
+ /// </summary>
+ /// <param name="column">A <see cref="Column"/> element</param>
+ /// <param name="longerThan">Generate a more specific name than provided.
+ /// If this is set, then the passed in name will have been generated by
+ /// this method on this instance. Can be <see langword="null"/></param>
+ /// <returns>A name for <paramref name="column"/>.</returns>
+ string GenerateColumnName(Column column, string longerThan);
+ /// <summary>
+ /// Generate a name for the provided <paramref name="constraint"/>
+ /// </summary>
+ /// <param name="constraint">A <see cref="Constraint"/> element</param>
+ /// <param name="longerThan">Generate a more specific name than provided.
+ /// If this is set, then the passed in name will have been generated by
+ /// this method on this instance. Can be <see langword="null"/></param>
+ /// <returns>A name for <paramref name="constraint"/>.</returns>
+ string GenerateConstraintName(Constraint constraint, string longerThan);
+ }
+ #endregion // IDatabaseNameGenerator interface
+ partial class ORMAbstractionToConceptualDatabaseBridgeDomainModel
+ {
+ private static class NameGeneration
+ {
+ #region GenerateAllNames method
+ public static void GenerateAllNames(Schema schema)
+ {
+ Dictionary<string, ConceptualDatabaseModelElement> tableNames = new Dictionary<string, ConceptualDatabaseModelElement>();
+ Dictionary<string, ConceptualDatabaseModelElement> tempNames = new Dictionary<string, ConceptualDatabaseModelElement>();
+ LinkedElementCollection<Table> tables = schema.TableCollection;
+ foreach (Table table in tables)
+ {
+ CallGeneratorForTableName(table, tableNames, null);
+
+ //column names
+ tempNames.Clear();
+ LinkedElementCollection<Column> columns = table.ColumnCollection;
+ foreach (Column column in columns)
+ {
+ CallGeneratorForColumnName(column, tempNames, null);
+ }
+
+ //constraint names
+ LinkedElementCollection<ReferenceConstraint> constraints;
+ if ((constraints = table.ReferenceConstraintCollection) != null)
+ {
+ tempNames.Clear();
+ foreach (ReferenceConstraint constraint in constraints)
+ {
+ CallGeneratorForConstraintName(constraint, tempNames, null);
+ }
+ }
+ }
+ }
+ #endregion // GenerateAllNames method
+ #region private helper methods
+ private static void CallGeneratorForTableName(Table table, Dictionary<string, ConceptualDatabaseModelElement> tableNames, string tableName)
+ {
+ CallGenerator(table, tableNames, tableName,
+ new GeneratorCall(delegate(ConceptualDatabaseModelElement element, string longerThan)
+ {
+ return GenerateTableName(element as Table, longerThan);
+ }));
+ }
+ private static void CallGeneratorForColumnName(Column column, Dictionary<string, ConceptualDatabaseModelElement> columnNames, string columnName)
+ {
+ CallGenerator(column, columnNames, columnName,
+ new GeneratorCall(delegate(ConceptualDatabaseModelElement element, string longerThan)
+ {
+ return GenerateColumnName(element as Column, longerThan);
+ }));
+ }
+ private static void CallGeneratorForConstraintName(Constraint constraint, Dictionary<string, ConceptualDatabaseModelElement> constraintNames, string constraintName)
+ {
+ CallGenerator(constraint, constraintNames, constraintName,
+ new GeneratorCall(delegate(ConceptualDatabaseModelElement element, string longerThan)
+ {
+ return GenerateConstraintName(element as Constraint, longerThan);
+ }));
+ }
+ delegate string GeneratorCall(ConceptualDatabaseModelElement element, string longerThan);
+ private static void CallGenerator(ConceptualDatabaseModelElement element, Dictionary<string, ConceptualDatabaseModelElement> existingNames, string curName, GeneratorCall generatorCall)
+ {
+ ConceptualDatabaseModelElement nameConflictElement = null;
+ while (true)
+ {
+ if (nameConflictElement != null)
+ {
+ existingNames[curName] = null;
+ CallGenerator(nameConflictElement, existingNames, curName, generatorCall);
+ }
+ curName = generatorCall(element, curName);
+
+ if (existingNames.ContainsKey(curName))
+ {
+ nameConflictElement = existingNames[curName];
+ }
+ else
+ {
+ break;
+ }
+ }
+ existingNames.Add(curName, element);
+ Table table;
+ Column column;
+ Constraint constraint;
+ if ((constraint = element as Constraint) != null)
+ {
+ constraint.Name = curName;
+ }
+ else if ((column = element as Column) != null)
+ {
+ column.Name = curName;
+ }
+ else if ((table = element as Table) != null)
+ {
+ table.Name = curName;
+ }
+ }
+ #endregion // private helper methods
+ #region UNDONE: temporary static imitation of an IDatabaseNameGenerator implementation
+ private static Regex myReplaceStrings;
+ private static Regex myIsNumber;
+ // 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)
+ {
+ CasingOption tableCase = CasingOption.Pascal;
+ string tableStringReplace = "";
+
+ ConceptType primaryConceptType = TableIsPrimarilyForConceptType.GetConceptType(table);
+ LinkedElementCollection<ConceptType> secondaryConceptTypes = TableIsAlsoForConceptType.GetConceptType(table);
+ StringBuilder name = new StringBuilder();
+ name.Append(primaryConceptType.Name);
+ if (secondaryConceptTypes != null)
+ {
+ foreach (ConceptType conceptType in secondaryConceptTypes)
+ {
+ name.Append(conceptType.Name);
+ if (longerThan == null || FinalizeName(name.ToString(), tableCase, tableStringReplace) != longerThan)
+ {
+ break;
+ }
+ }
+ }
+
+ if (myCounts != null)
+ {
+ myCounts.Clear();
+ }
+
+ string finalName = FinalizeName(name.ToString(), tableCase, tableStringReplace);
+ while (finalName == longerThan)
+ {
+ finalName += "_";
+ }
+ return finalName;
+ }
+ private static string GenerateColumnName(Column column, string longerThan)
+ {
+ CasingOption columnCasing = CasingOption.Pascal;
+ string columnStringReplace = "";
+
+ string finalName;
+ LinkedElementCollection<ConceptTypeChild> path = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column);
+ if (path.Count < 1)
+ {
+ finalName = FinalizeName(column.Name, columnCasing, columnStringReplace);
+ return EnsureDiff(finalName, longerThan);
+ }
+
+ Guid tableObjectTypeID = ConceptTypeIsForObjectType.GetObjectType(TableIsPrimarilyForConceptType.GetConceptType(column.Table)).Id;
+ StringBuilder name = new StringBuilder();
+
+ bool hasUnary = false;
+ int predicateTextCount = 0;
+ bool alwaysKeepText = false;
+ bool hasRoleOrHyphenBound = false;
+ foreach (ConceptTypeChild link in path)
+ {
+ LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(link);
+ //get a role name for each fact type, or generate one from the reading
+ foreach (FactType factType in factTypes)
+ {
+ string roleName;
+ LinkedElementCollection<RoleBase> factTypeRoles = factType.RoleCollection;
+ int? unaryRoleIndex = FactType.GetUnaryRoleIndex(factTypeRoles);
+ if (unaryRoleIndex.HasValue)
+ {
+ Role unaryRole = factTypeRoles[unaryRoleIndex.Value].Role;
+ //get the role name, if supplied
+ roleName = unaryRole.Name;
+ if (string.IsNullOrEmpty(roleName))
+ {
+ if (IsPreferredIdentifierFactType(factType, unaryRole))
+ {
+ alwaysKeepText = true;
+ //we don't generate a role name from the reading if the fact type participates in the primary reference scheme
+ continue;
+ }
+
+ roleName = GetRoleName(factType, factTypeRoles, unaryRole, unaryRoleIndex, ref hasRoleOrHyphenBound);
+ }
+ else
+ {
+ hasRoleOrHyphenBound = true;
+ }
+ hasUnary = true;
+ }
+ else
+ {
+ RoleBase towardsRoleBase = FactTypeMapsTowardsRole.GetTowardsRole(factType);
+ RoleBase oppositeRoleBase = towardsRoleBase.OppositeRoleAlwaysResolveProxy;
+ roleName = oppositeRoleBase.Role.Name;
+ if (string.IsNullOrEmpty(roleName))
+ {
+ if (IsPreferredIdentifierFactType(factType, towardsRoleBase.Role))
+ {
+ alwaysKeepText = true;
+ continue;
+ }
+
+ roleName = GetRoleName(factType, factTypeRoles, oppositeRoleBase, null, ref hasRoleOrHyphenBound);
+ }
+ else
+ {
+ hasRoleOrHyphenBound = true;
+ }
+ }
+ if (!string.IsNullOrEmpty(roleName))
+ {
+ ++predicateTextCount;
+ }
+ name.Append(roleName);
+ }
+
+ //value type name
+ InformationTypeFormat informationTypeFormat;
+ if ((informationTypeFormat = link.Target as InformationTypeFormat) != null)
+ {
+ string valueTypeName = "";
+
+ //check if this value type is the preferred identifier,
+ //and if so prepend the object type name to the value type name
+ LinkedElementCollection<ConceptType> types = informationTypeFormat.ConceptTypeCollection;
+ if (types.Count == 1)
+ {
+ ObjectType preferredFor = ConceptTypeIsForObjectType.GetObjectType(types[0]);
+ LinkedElementCollection<Role> identifiers = preferredFor.ResolvedPreferredIdentifier.RoleCollection;
+ if (identifiers.Count == 1)
+ {
+ if (identifiers[0].RolePlayer.Id == InformationTypeFormatIsForValueType.GetValueType(informationTypeFormat).Id)
+ {
+ if (!informationTypeFormat.Name.StartsWith(preferredFor.Name))
+ {
+ valueTypeName = preferredFor.Name + "_";
+ }
+ }
+ }
+ }
+
+ valueTypeName += informationTypeFormat.Name;
+
+ if (!hasUnary || (longerThan != null && longerThan == FinalizeName(name.ToString(), columnCasing, columnStringReplace)))
+ {
+ if (!(hasRoleOrHyphenBound || alwaysKeepText) && (predicateTextCount == 1 &&
+ (longerThan == null || longerThan != FinalizeName(valueTypeName, columnCasing, columnStringReplace))))
+ {
+ //if the only existing text is a single role name generated from predicate text, remove it
+ name.Remove(0, name.Length);
+ name.Append(valueTypeName);
+ }
+ else if (!hasRoleOrHyphenBound || FinalizeName(name.ToString(), columnCasing, columnStringReplace) == longerThan)
+ {
+ name.Append(valueTypeName);
+ }
+ }
+ }
+ }
+
+ finalName = FinalizeName(name.ToString(), columnCasing, columnStringReplace);
+ return EnsureDiff(finalName, longerThan);
+ }
+
+ private static string GenerateConstraintName(Constraint constraint, string longerThan)
+ {
+ ReferenceConstraint refConstraint = constraint as ReferenceConstraint;
+ if (refConstraint != null)
+ {
+ StringBuilder name = new StringBuilder(refConstraint.SourceTable.Name);
+ name.Append("_FK");
+ return EnsureDiff(name.ToString(), longerThan);
+ }
+ return constraint.Name;
+ }
+ private enum CasingOption
+ {
+ Pascal,
+ Camel,
+ Flat,
+ Upper,
+ }
+ private static string FinalizeName(string name, CasingOption casing, string spaceReplaceString)
+ {
+ for (int i = name.Length; --i > -1; )
+ {
+ if (char.IsUpper(name, i))
+ {
+ name = name.Insert(i, " ");
+ }
+ }
+
+ string[] words = name.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
+ if (words.Length > 0)
+ {
+ switch (casing)
+ {
+ case CasingOption.Camel:
+ words[0] = words[0].ToLowerInvariant();
+ CapitalizeWords(words, 1);
+ break;
+ case CasingOption.Pascal:
+ CapitalizeWords(words, 0);
+ break;
+ }
+ StringBuilder builder = new StringBuilder(words[0]);
+ for (int i = 1; i < words.Length; ++i)
+ {
+ builder.Append(spaceReplaceString);
+ builder.Append(words[i]);
+ }
+ name = builder.ToString();
+
+ switch (casing)
+ {
+ case CasingOption.Flat:
+ name = name.ToLowerInvariant();
+ break;
+ case CasingOption.Upper:
+ name = name.ToUpperInvariant();
+ break;
+ }
+ }
+ else
+ {
+ name = "";
+ }
+
+ return name;
+ }
+
+ private static void CapitalizeWords(string[] words, int startIndex)
+ {
+ for (int i = startIndex; i < words.Length; ++i)
+ {
+ words[i] = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(words[i]);
+ }
+ }
+ private static string EnsureDiff(string name, string longerThan)
+ {
+ if (longerThan != null && longerThan.StartsWith(name))
+ {
+ bool isSame = name == longerThan;
+ if (!isSame)
+ {
+ if (myIsNumber == null)
+ {
+ myIsNumber = new Regex(@"\d+", RegexOptions.RightToLeft | RegexOptions.Compiled);
+ }
+ string endNumbers = longerThan.Substring(name.Length);
+ Match longerThanMatches = myIsNumber.Match(endNumbers);
+ if (longerThanMatches.Success && longerThanMatches.Index + longerThanMatches.Length == endNumbers.Length)
+ {
+ isSame = true;
+ }
+ }
+
+ if (isSame)
+ {
+ if (myCounts == null)
+ {
+ myCounts = new Dictionary<string, int>();
+ }
+ int curCount;
+ if (myCounts.ContainsKey(name))
+ {
+ curCount = myCounts[name];
+ ++myCounts[name];
+ }
+ else
+ {
+ curCount = 1;
+ myCounts.Add(name, 2);
+ }
+ name += curCount.ToString();
+ }
+ }
+ return name;
+ }
+ private static bool IsPreferredIdentifierFactType(FactType factType, Role role)
+ {
+ return role.RolePlayer.ResolvedPreferredIdentifier.FactTypeCollection.Contains(factType);
+ }
+ private static ReadingOrder GetReading(FactType factType, Role role, bool isUnary)
+ {
+ if (!isUnary)
+ {
+ //get the reading in the correct direction, if possible
+ ReadingOrder readingOrder = factType.FindMatchingReadingOrder(new RoleBase[] { role.OppositeRoleAlwaysResolveProxy, role });
+ if (null != readingOrder)
+ {
+ return readingOrder;
+ }
+ }
+
+ LinkedElementCollection<ReadingOrder> readingOrders = factType.ReadingOrderCollection;
+
+ foreach (ReadingOrder readingOrder in readingOrders)
+ {
+ return readingOrder;
+ }
+
+ //if there is no reading return the object type name
+ return null;
+ }
+ private static string GetRoleName(FactType factType, LinkedElementCollection<RoleBase> factTypeRoles, RoleBase role, int? unaryRoleIndex, ref bool alwaysKeepText)
+ {
+ string roleName = role.Role.Name;
+ if (string.IsNullOrEmpty(roleName))
+ {
+ roleName = GetRoleNameFromPredicateText(factType, factTypeRoles, role, unaryRoleIndex, ref alwaysKeepText);
+ }
+ return roleName;
+ }
+ private static string GetRoleNameFromPredicateText(FactType factType, LinkedElementCollection<RoleBase> factTypeRoles, RoleBase role, int? unaryRoleIndex, ref bool alwaysKeepText)
+ {
+ bool isUnary = unaryRoleIndex.HasValue;
+ ReadingOrder readingOrder = GetReading(factType, role.Role, isUnary);
+ string rolePlayerName = role.Role.RolePlayer.Name;
+ if (readingOrder == null)
+ {
+ return rolePlayerName;
+ }
+ else
+ {
+ IReading reading = readingOrder.PrimaryReading;
+ // 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 hyphenBoundRolePlayerName = hyphenBinder.HyphenBindRoleReplacement(rolePlayerName, factTypeRoles.IndexOf(role));
+ if ((object)hyphenBoundRolePlayerName != (object)rolePlayerName)
+ {
+ alwaysKeepText = true;
+ // The hyphen binder had an opinion
+ return hyphenBoundRolePlayerName;
+ }
+ string text = reading.Text;
+ if (myReplaceStrings == null)
+ {
+ myReplaceStrings = new Regex(@"{\d+}", RegexOptions.Compiled);
+ }
+ text = myReplaceStrings.Replace(text, "");
+ text = text.Replace(" a ", " ").Replace(" an ", " ").Replace(" the ", " ");
+ if (!isUnary)
+ {
+ text = text.Replace(" has ", " ");
+ }
+ else if (text.Trim().ToLowerInvariant() == "has")
+ {
+ text = " ";
+ }
+ return text;
+ }
+ }
+ #endregion //UNDONE: temporary static immitation of an IDatabaseNameGenerator implementation
+ }
+ }
+}
Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.cs
===================================================================
--- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.cs 2007-08-30 17:19:27 UTC (rev 1099)
+++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.cs 2007-08-30 17:21:57 UTC (rev 1100)
@@ -38,10 +38,13 @@
typeof(ModificationTracker).GetNestedType("AssimilationMappingAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(ModificationTracker).GetNestedType("AssimilationMappingChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(ModificationTracker).GetNestedType("ConceptTypeAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+ typeof(ModificationTracker).GetNestedType("ConceptTypeChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(ModificationTracker).GetNestedType("ConceptTypeChildChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(ModificationTracker).GetNestedType("ConceptTypeDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+ typeof(ModificationTracker).GetNestedType("FactTypeNameChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(ModificationTracker).GetNestedType("InformationTypeFormatAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(ModificationTracker).GetNestedType("InformationTypeFormatDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
+ typeof(ModificationTracker).GetNestedType("RoleNameChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(ModificationTracker).GetNestedType("UniquenessDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(AssimilationMapping).GetNestedType("AssimilationMappingAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic),
typeof(AssimilationMapping).GetNestedType("AssimilationMappingChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic)};
@@ -78,7 +81,7 @@
{
Microsoft.VisualStudio.Modeling.RuleManager ruleManager = store.RuleManager;
Type[] disabledRuleTypes = ORMAbstractionToConceptualDatabaseBridgeDomainModel.CustomDomainModelTypes;
- for (int i = 0; i < 11; ++i)
+ for (int i = 0; i < 14; ++i)
{
ruleManager.EnableRule(disabledRuleTypes[i]);
}
@@ -199,6 +202,32 @@
Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.ConceptTypeAddedRule");
}
}
+ [Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORMAbstraction.ConceptType))]
+ private sealed class ConceptTypeChangedRuleClass : Microsoft.VisualStudio.Modeling.ChangeRule
+ {
+ [System.Diagnostics.DebuggerStepThrough()]
+ public ConceptTypeChangedRuleClass()
+ {
+ base.IsEnabled = false;
+ }
+ /// <summary>
+ /// Provide the following method in class:
+ /// Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker
+ /// /// <summary>
+ /// /// ChangeRule: typeof(Neumont.Tools.ORMAbstraction.ConceptType)
+ /// /// </summary>
+ /// private static void ConceptTypeChangedRule(ElementPropertyChangedEventArgs e)
+ /// {
+ /// }
+ /// </summary>
+ [System.Diagnostics.DebuggerStepThrough()]
+ public override void ElementPropertyChanged(Microsoft.VisualStudio.Modeling.ElementPropertyChangedEventArgs e)
+ {
+ Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.ConceptTypeChangedRule");
+ ModificationTracker.ConceptTypeChangedRule(e);
+ Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.ConceptTypeChangedRule");
+ }
+ }
[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORMAbstraction.ConceptTypeChild))]
private sealed class ConceptTypeChildChangedRuleClass : Microsoft.VisualStudio.Modeling.ChangeRule
{
@@ -251,6 +280,32 @@
Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.ConceptTypeDeletedRule");
}
}
+ [Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.FactType))]
+ private sealed class FactTypeNameChangedRuleClass : Microsoft.VisualStudio.Modeling.ChangeRule
+ {
+ [System.Diagnostics.DebuggerStepThrough()]
+ public FactTypeNameChangedRuleClass()
+ {
+ base.IsEnabled = false;
+ }
+ /// <summary>
+ /// Provide the following method in class:
+ /// Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker
+ /// /// <summary>
+ /// /// ChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.FactType)
+ /// /// </summary>
+ /// private static void FactTypeNameChangedRule(ElementPropertyChangedEventArgs e)
+ /// {
+ /// }
+ /// </summary>
+ [System.Diagnostics.DebuggerStepThrough()]
+ public override void ElementPropertyChanged(Microsoft.VisualStudio.Modeling.ElementPropertyChangedEventArgs e)
+ {
+ Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.FactTypeNameChangedRule");
+ ModificationTracker.FactTypeNameChangedRule(e);
+ Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.FactTypeNameChangedRule");
+ }
+ }
[Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORMAbstraction.AbstractionModelHasInformationTypeFormat))]
private sealed class InformationTypeFormatAddedRuleClass : Microsoft.VisualStudio.Modeling.AddRule
{
@@ -303,6 +358,32 @@
Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.InformationTypeFormatDeletedRule");
}
}
+ [Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.Role))]
+ private sealed class RoleNameChangedRuleClass : Microsoft.VisualStudio.Modeling.ChangeRule
+ {
+ [System.Diagnostics.DebuggerStepThrough()]
+ public RoleNameChangedRuleClass()
+ {
+ base.IsEnabled = false;
+ }
+ /// <summary>
+ /// Provide the following method in class:
+ /// Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker
+ /// /// <summary>
+ /// /// ChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.Role)
+ /// /// </summary>
+ /// private static void RoleNameChangedRule(ElementPropertyChangedEventArgs e)
+ /// {
+ /// }
+ /// </summary>
+ [System.Diagnostics.DebuggerStepThrough()]
+ public override void ElementPropertyChanged(Microsoft.VisualStudio.Modeling.ElementPropertyChangedEventArgs e)
+ {
+ Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.RoleNameChangedRule");
+ ModificationTracker.RoleNameChangedRule(e);
+ Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel.ModificationTracker.RoleNameChangedRule");
+ }
+ }
[Microsoft.VisualStudio.Modeling.RuleOn(typeof(UniquenessConstraintIsForUniqueness))]
private sealed class UniquenessDeletedRuleClass : Microsoft.VisualStudio.Modeling.DeleteRule
{
Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.xml
===================================================================
--- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.xml 2007-08-30 17:19:27 UTC (rev 1099)
+++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.AttachRules.xml 2007-08-30 17:21:57 UTC (rev 1100)
@@ -29,18 +29,27 @@
<arg:AddRule methodName="ConceptTypeAddedRule">
<arg:RuleOn targetType="AbstractionModelHasConceptType" targetTypeQualifier="Neumont.Tools.ORMAbstraction"/>
</arg:AddRule>
+ <arg:ChangeRule methodName="ConceptTypeChangedRule">
+ <arg:RuleOn targetType="ConceptType" targetTypeQualifier="Neumont.Tools.ORMAbstraction"/>
+ </arg:ChangeRule>
<arg:ChangeRule methodName="ConceptTypeChildChangedRule">
<arg:RuleOn targetType="ConceptTypeChild" targetTypeQualifier="Neumont.Tools.ORMAbstraction"/>
</arg:ChangeRule>
<arg:DeleteRule methodName="ConceptTypeDeletedRule">
<arg:RuleOn targetType="AbstractionModelHasConceptType" targetTypeQualifier="Neumont.Tools.ORMAbstraction"/>
</arg:DeleteRule>
+ <arg:ChangeRule methodName="FactTypeNameChangedRule">
+ <arg:RuleOn targetType="FactType" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
+ </arg:ChangeRule>
<arg:AddRule methodName="InformationTypeFormatAddedRule">
<arg:RuleOn targetType="AbstractionModelHasInformationTypeFormat" targetTypeQualifier="Neumont.Tools.ORMAbstraction"/>
</arg:AddRule>
<arg:DeleteRule methodName="InformationTypeFormatDeletedRule">
<arg:RuleOn targetType="AbstractionModelHasInformationTypeFormat" targetTypeQualifier="Neumont.Tools.ORMAbstraction"/>
</arg:DeleteRule>
+ <arg:ChangeRule methodName="RoleNameChangedRule">
+ <arg:RuleOn targetType="Role" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel"/>
+ </arg:ChangeRule>
<arg:DeleteRule methodName="UniquenessDeletedRule">
<arg:RuleOn targetType="UniquenessConstraintIsForUniqueness"/>
</arg:DeleteRule>
Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs
===================================================================
--- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-08-30 17:19:27 UTC (rev 1099)
+++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-08-30 17:21:57 UTC (rev 1100)
@@ -196,7 +196,7 @@
}
// Change all names to a more apropriate verson.
- //NameGeneration.GenerateAllNames(schema);
+ NameGeneration.GenerateAllNames(schema);
}
/// <summary>
Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.csproj
===================================================================
--- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.csproj 2007-08-30 17:19:27 UTC (rev 1099)
+++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.csproj 2007-08-30 17:21:57 UTC (rev 1100)
@@ -134,6 +134,7 @@
<Compile Include="AssimilationMapping.cs" />
<Compile Include="MappingCustomizationModel.cs" />
<Compile Include="ModificationTracker.cs" />
+ <Compile Include="NameGeneration.cs" />
<Compile Include="OialDcilBridge.AttachRules.cs">
<AutoGen>True</AutoGen>
<DependentUpon>OialDcilBridge.AttachRules.xml</DependentUpon>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|