You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
(21) |
Sep
(25) |
Oct
(13) |
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(6) |
Sep
(1) |
Oct
(1) |
Nov
(8) |
Dec
(3) |
2009 |
Jan
(5) |
Feb
(3) |
Mar
(10) |
Apr
(6) |
May
(3) |
Jun
(4) |
Jul
(1) |
Aug
(3) |
Sep
(5) |
Oct
(1) |
Nov
(2) |
Dec
(2) |
2010 |
Jan
|
Feb
(3) |
Mar
(2) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
(2) |
Aug
|
Sep
(3) |
Oct
(2) |
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(3) |
Jul
(1) |
Aug
|
Sep
|
Oct
(2) |
Nov
(1) |
Dec
|
2012 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(4) |
Nov
(4) |
Dec
(2) |
2013 |
Jan
(1) |
Feb
(1) |
Mar
(1) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(1) |
Aug
(1) |
Sep
|
Oct
(1) |
Nov
(3) |
Dec
(2) |
2014 |
Jan
|
Feb
|
Mar
|
Apr
(3) |
May
(1) |
Jun
|
Jul
(2) |
Aug
(1) |
Sep
|
Oct
|
Nov
(2) |
Dec
(5) |
2015 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <mcu...@us...> - 2007-10-15 05:27:52
|
Revision: 1145 http://orm.svn.sourceforge.net/orm/?rev=1145&view=rev Author: mcurland Date: 2007-10-14 22:27:49 -0700 (Sun, 14 Oct 2007) Log Message: ----------- Changed a section that was improperly casting a Role and thus preventing the generation of a spanning uniqueness on a relationship played by an objectified fact type with a spanning uniqueness. refs #327. Modified Paths: -------------- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs Modified: trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs =================================================================== --- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-09-20 20:57:41 UTC (rev 1144) +++ trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-10-15 05:27:49 UTC (rev 1145) @@ -1185,7 +1185,7 @@ { continue; } - Role oppositeRole = (Role)role.OppositeRoleAlwaysResolveProxy; + Role oppositeRole = role.OppositeRoleAlwaysResolveProxy.Role; // Recursivly call this for each of objectType's preferred identifier object types. foreach (ConstraintRoleSequence constraintRoleSequence in oppositeRole.ConstraintRoleSequenceCollection) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:57:37
|
Revision: 1144 http://orm.svn.sourceforge.net/orm/?rev=1144&view=rev Author: mcurland Date: 2007-09-20 13:57:41 -0700 (Thu, 20 Sep 2007) Log Message: ----------- FindTarget needs to handle alternate absorption paths when building foreign keys in absorbed relationships in complex subtyping graphs. refs #328 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-20 20:56:41 UTC (rev 1143) +++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-20 20:57:41 UTC (rev 1144) @@ -1349,21 +1349,41 @@ // Remove everything at and after index, and add everything before it int index; - for (index = 0; index < targetAssimilationPath.Count; index++) + int officialAssimilationPathCount = targetAssimilationPath.Count; + for (index = 0; index < officialAssimilationPathCount; index++) { if (targetAssimilationPath[index].Parent == informationTypeParent) { break; } } -#if DEBUG - for (int i = targetAssimilationPath.Count - 1, j = 0; i >= index; i--, j++) + + int removeCount = officialAssimilationPathCount - index; + for (int i = officialAssimilationPathCount - 1, j = 0; i >= index; i--, j++) { - Debug.Assert(targetCtcPath[j] == targetAssimilationPath[i]); + if (targetCtcPath[j] != targetAssimilationPath[i]) + { + // Handle alternate assimilation paths + ConceptType testAssimilator = targetAssimilationPath[index].AssimilatorConceptType; + int targetPathCount = targetCtcPath.Count; + for (int k = j + 1; k < targetPathCount; ++k) + { + ConceptTypeAssimilatesConceptType targetAssimilation = targetCtcPath[k] as ConceptTypeAssimilatesConceptType; + Debug.Assert(targetAssimilation != null, "Alternate assimilation paths should rejoin before we run out of assimilations."); + if (targetAssimilation != null) + { + if (targetAssimilation.AssimilatorConceptType == testAssimilator) + { + removeCount = k + 1; + break; + } + } + } + break; + } } -#endif //DEBUG - targetCtcPath.RemoveRange(0, targetAssimilationPath.Count - index); + targetCtcPath.RemoveRange(0, removeCount); for (int i = index - 1; i >= 0; i--) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:56:37
|
Revision: 1143 http://orm.svn.sourceforge.net/orm/?rev=1143&view=rev Author: mcurland Date: 2007-09-20 13:56:41 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Undo part of previous checkin [1142]. This picks up role names better, the other used reference mode naming better. refs #338 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs Modified: trunk/RelationalModel/OialDcilBridge/NameGeneration.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-20 20:55:43 UTC (rev 1142) +++ trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-20 20:56:41 UTC (rev 1143) @@ -459,7 +459,7 @@ bool hasSubtypeNode = false; FactType mainFactType = null; //find the first non subtype fact type - for (int i = pathCount - 1; i >= 0; --i) + for (int i = 0; i < pathCount; ++i) { link = path[i]; LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(link); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:55:40
|
Revision: 1142 http://orm.svn.sourceforge.net/orm/?rev=1142&view=rev Author: mcurland Date: 2007-09-20 13:55:43 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Change column default naming to Camel from Pascal per request from Terry. Also, does not case words with any adjacent upper case values. This is not a complete solution because parts of generated names need to be considered and cased individually, not as a block. See comments introduced in this changeset for more information. refs #338 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs Modified: trunk/RelationalModel/OialDcilBridge/NameGeneration.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-20 20:54:44 UTC (rev 1141) +++ trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-20 20:55:43 UTC (rev 1142) @@ -439,7 +439,7 @@ private string GenerateColumnName(Column column, string longerThan) { // UNDONE: use these two varables to reflect preference customization - CasingOption columnCase = CasingOption.Pascal; + CasingOption columnCase = CasingOption.Camel; string columnSpace = ""; //the string is used when possible to avoid using the list for a single entry @@ -459,7 +459,7 @@ bool hasSubtypeNode = false; FactType mainFactType = null; //find the first non subtype fact type - for (int i = 0; i < pathCount; ++i) + for (int i = pathCount - 1; i >= 0; --i) { link = path[i]; LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(link); @@ -725,6 +725,15 @@ } private string GetFinalName(string singleName, List<string> nameCollection, string space, CasingOption casing) { + // UNDONE: There are several things we need to do this correctly. + // Object type names cannot be treated as atomic unit. + // 1) ValueType names may be composed of EntityType and reference mode names combined with + // a format string. + // 2) EntityType names may be composed of a format string combining EntityType/ValueType/ReferenceMode names + // that also need to be considered as atomic names and a format string to combine them + // 3) ReferenceModeNames may be units, which should never be cased. + // + // Camel gives inconsistent results until these are done, although it is used as the column default. string finalName; if (null == nameCollection) { @@ -790,17 +799,47 @@ switch (casing) { case CasingOption.Camel: - return DoFirstLetterCase(name, false, textInfo); + return TestHasAdjacentUpperCase(name) ? name : DoFirstLetterCase(name, false, textInfo); case CasingOption.Pascal: - return DoFirstLetterCase(name, true, textInfo); + return TestHasAdjacentUpperCase(name) ? name : DoFirstLetterCase(name, true, textInfo); case CasingOption.Flat: - return textInfo.ToLower(name); + return TestHasAdjacentUpperCase(name) ? name : textInfo.ToLower(name); case CasingOption.Upper: return textInfo.ToUpper(name); } return null; } + private bool TestHasAdjacentUpperCase(string name) + { + if (!string.IsNullOrEmpty(name)) + { + int length = name.Length; + bool previousCharUpper = false; + for (int i = 0; i < length; ++i) + { + // UNDONE: Hack until we can consider individual parts of + // reference mode names. Ignore anything after a separator. + if (!Char.IsLetterOrDigit(name, i)) + { + return false; + } + if (Char.IsUpper(name, i)) + { + if (previousCharUpper) + { + return true; + } + previousCharUpper = true; + } + else + { + previousCharUpper = false; + } + } + } + return false; + } private string DoFirstLetterCase(string name, bool upper, TextInfo textInfo) { char c = name[0]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:54:41
|
Revision: 1141 http://orm.svn.sourceforge.net/orm/?rev=1141&view=rev Author: mcurland Date: 2007-09-20 13:54:44 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Column.IsNullable was not set correctly when the ConceptTypeChild path crossed an assimilation, and separation was generating column references to orphaned columns that caused the file to fail reload. refs #328 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-20 20:53:35 UTC (rev 1140) +++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-20 20:54:44 UTC (rev 1141) @@ -157,7 +157,7 @@ /// <summary> /// Generates the conceptual database model for a given Schema and AbstractionModel. /// The generation of the Conceptual Database Model includes the population of all tables with - /// Columns, Uniquenesses, Foreign Keys, and Manditory restrictions. + /// Columns, Uniquenesses, Foreign Keys, and Mandatory restrictions. /// </summary> private static void FullyGenerateConceptualDatabaseModel(Schema schema, AbstractionModel sourceModel) { @@ -272,27 +272,35 @@ #endif // OLDPARTITIONCODE - Collection<ConceptTypeAssimilatesConceptType> separatedConceptTypes = new Collection<ConceptTypeAssimilatesConceptType>(); - - // For every concept type create all columns that they represent, perform separations, and map unqiuenesses that they participate in. + // For every concept type create all columns that they represent, map uniquenesses that they participate in. foreach (ConceptType conceptType in conceptTypes) { CreateColumns(conceptType); + CreateUniquenessConstraints(conceptType); + } + // Make a second pass over the concept types to population separation columns, constraint, and uniquenesses. + // Note that we do this second so that any target columns already exist + Dictionary<ConceptTypeAssimilatesConceptType, object> separatedConceptTypes = null; + foreach (ConceptType conceptType in conceptTypes) + { bool isPreferredForChildFound = false; foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilation in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType))//GetAssimilationsForConceptType(conceptType)) { - if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(conceptTypeAssimilation) == AssimilationAbsorptionChoice.Separate && !separatedConceptTypes.Contains(conceptTypeAssimilation)) + if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(conceptTypeAssimilation) == AssimilationAbsorptionChoice.Separate && + (separatedConceptTypes == null || !separatedConceptTypes.ContainsKey(conceptTypeAssimilation))) { DoSeparation(conceptTypeAssimilation, ref isPreferredForChildFound); - separatedConceptTypes.Add(conceptTypeAssimilation); + if (separatedConceptTypes == null) + { + separatedConceptTypes = new Dictionary<ConceptTypeAssimilatesConceptType, object>(); + } + separatedConceptTypes.Add(conceptTypeAssimilation, null); } } - - CreateUniquenessConstraints(conceptType); } - // For each table in the schema generate any foreign keys it contains and detemine witch of it's columns are manditory and nullible. + // For each table in the schema generate any foreign keys it contains and detemine witch of it's columns are mandatory and nullable. foreach (Table table in schema.TableCollection) { CreateForeignKeys(table); @@ -330,7 +338,10 @@ ProcessConceptTypeForTable(assimilation.AssimilatedConceptType, table, assimilationPath); - ConceptTypeAssimilatesConceptType poppedAssimilation = assimilationPath.Pop(); +#if DEBUG + ConceptTypeAssimilatesConceptType poppedAssimilation = +#endif // DEBUG + assimilationPath.Pop(); Debug.Assert(assimilation == poppedAssimilation); } } @@ -345,7 +356,10 @@ ProcessConceptTypeForTable(assimilation.AssimilatorConceptType, table, assimilationPath); - ConceptTypeAssimilatesConceptType poppedAssimilation = assimilationPath.Pop(); +#if DEBUG + ConceptTypeAssimilatesConceptType poppedAssimilation = +#endif // DEBUG + assimilationPath.Pop(); Debug.Assert(assimilation == poppedAssimilation); } } @@ -551,11 +565,6 @@ } - //foreach (ConceptTypeChild conceptTypeChild in ConceptTypeChild.GetLinksToTargetCollection(conceptType)) - //{ - // columnsForConceptType.AddRange(GetColumnsForConceptTypeChild(conceptTypeChild, new List<ConceptTypeChild>())); - //} - Table conceptTypeTable = TableIsPrimarilyForConceptType.GetTable(conceptType); if (conceptTypeTable != null) { @@ -677,76 +686,62 @@ throw new InvalidOperationException(); } - - /// <summary> + /// A callback delegate for <see cref="GetColumnsForConceptTypeChild"/> + /// </summary> + /// <param name="childInformationType">The current <see cref="InformationType"/></param> + /// <param name="childPathStack">The path to the <paramref name="childInformationType"/>. Converting + /// the stack to an array and reversing will give the assimilation path. The childInformationType will be on the top of the stack. + /// The stack is <see langword="null"/> if no stack is passed into GetColumnsForConceptTypeChild.</param> + private delegate void ProcessChildInformationType(InformationType childInformationType, Stack<ConceptTypeChild> childPathStack); + /// <summary> /// GetColumnsForConceptTypeChild gets the <see cref="Column"/> coresponding to a <see cref="ConceptTypeChild"/>. /// </summary> /// <remarks> - /// GetColumnsForConceptTypeChild populates a list of Columns pertaining to a ConceptTypeChild, - /// Columns are only added if the ConceptTypeChild is an Information Type, if the ConceptTypeChild is of type - /// ConceptTypeRelatesToConceptType or ConceptTypeAssimilatesConceptType then it recursively calls itself using - /// the preffered target ConceptType of the ConceptTypeChild as the new ConceptTypeChildren, adding the result to the ColumnList. + /// GetColumnsForConceptTypeChild enables a callback for each InformationType. The callback delegate can create + /// a new column or use the callback for information purposes only. /// </remarks> - /// <param name="conceptTypeChild"></param> - /// <param name="conceptTypeChildPath">ConceptTypeChildPath is populated in GetColumnsForConceptTypeChild, - /// but may already contain ConceptTypeChildren.</param> - private static List<Column> GetColumnsForConceptTypeChild(ConceptTypeChild conceptTypeChild, List<ConceptTypeChild> conceptTypeChildPath) + /// <param name="conceptTypeChild">The child to process</param> + /// <param name="conceptTypeChildPath">A stack of preceding children in the path. Provide an empty starting stack + /// if stack information is required for the callback.</param> + /// <param name="informationTypeCallback">A callback method to process informaton types</param> + private static void GetColumnsForConceptTypeChild(ConceptTypeChild conceptTypeChild, Stack<ConceptTypeChild> conceptTypeChildPath, ProcessChildInformationType informationTypeCallback) { - List<Column> columnList = new List<Column>(); - conceptTypeChildPath.Add(conceptTypeChild); + if (conceptTypeChildPath != null) + { + conceptTypeChildPath.Push(conceptTypeChild); + } + InformationType informationType = conceptTypeChild as InformationType; - if (conceptTypeChild is InformationType) + if (null != (informationType = conceptTypeChild as InformationType)) { - Column informationTypeColumn = new Column(conceptTypeChild.Store, - new PropertyAssignment[]{ - new PropertyAssignment(Column.NameDomainPropertyId, conceptTypeChild.Name)}); - ColumnHasConceptTypeChild.GetConceptTypeChildPath(informationTypeColumn).AddRange(conceptTypeChildPath); - columnList.Add(informationTypeColumn); + informationTypeCallback(informationType, conceptTypeChildPath); } - else if (conceptTypeChild is ConceptTypeRelatesToConceptType) + else { - - ConceptType relatedConceptType = (ConceptType)conceptTypeChild.Target; - List<ConceptTypeChild> preferredList = GetPreferredConceptTypeChildrenForConceptType(relatedConceptType); - foreach (ConceptTypeChild child in preferredList) + ConceptType recursePreferredForConceptType = null; + if (conceptTypeChild is ConceptTypeRelatesToConceptType) { - if (child == preferredList[preferredList.Count - 1]) - { - - columnList.AddRange(GetColumnsForConceptTypeChild(child, conceptTypeChildPath)); - - //conceptTypeChildPath.Clear(); - //columnList.AddRange(GetColumnsForConceptTypeChild(child, conceptTypeChildPath)); - } - else - { - List<ConceptTypeChild> clonedConceptTypeChildPath = new List<ConceptTypeChild>(conceptTypeChildPath); - columnList.AddRange(GetColumnsForConceptTypeChild(child, clonedConceptTypeChildPath)); - } + recursePreferredForConceptType = (ConceptType)conceptTypeChild.Target; } - return columnList; - } - else if (conceptTypeChild is ConceptTypeAssimilatesConceptType) - { - ConceptType targetConceptType = (ConceptType)conceptTypeChild.Parent; - List<ConceptTypeChild> preferredList = GetPreferredConceptTypeChildrenForConceptType(targetConceptType); - foreach (ConceptTypeChild child in preferredList) + else if (conceptTypeChild is ConceptTypeAssimilatesConceptType) { - if (child == preferredList[preferredList.Count - 1]) + recursePreferredForConceptType = conceptTypeChild.Parent; + } + if (recursePreferredForConceptType != null) + { + IList<ConceptTypeChild> preferredList = GetPreferredConceptTypeChildrenForConceptType(recursePreferredForConceptType); + int preferredCount = preferredList.Count; + for (int i = 0; i < preferredCount; ++i) { - columnList.AddRange(GetColumnsForConceptTypeChild(child, conceptTypeChildPath)); + GetColumnsForConceptTypeChild(preferredList[i], conceptTypeChildPath, informationTypeCallback); } - else - { - List<ConceptTypeChild> clonedConceptTypeChildPath = new List<ConceptTypeChild>(conceptTypeChildPath); - columnList.AddRange(GetColumnsForConceptTypeChild(child, clonedConceptTypeChildPath)); - } } - return columnList; } - - return columnList; + if (conceptTypeChildPath != null) + { + conceptTypeChildPath.Pop(); + } } /// <summary> @@ -790,40 +785,41 @@ /// GetPreferredConceptTypeChildrenForConceptType parses through the uniquenesses of a single concept type, /// adding all ConceptTypeChildren of any Preferred Uniqueness. If there are no conceptTypeChildren that meet this critria /// then it checks for anyConceptTypeAssimilatesConceptTypes within the Assimillator collection, and finally through the Assimilated Collection - /// returning the list of all ConceptTypeChildren that are Prefered for the ConceptType. + /// returning the list of all ConceptTypeChildren that are Preferred for the ConceptType. /// </summary> - private static List<ConceptTypeChild> GetPreferredConceptTypeChildrenForConceptType(ConceptType conceptType) + private static IList<ConceptTypeChild> GetPreferredConceptTypeChildrenForConceptType(ConceptType conceptType) { foreach (Uniqueness uniqueness in conceptType.UniquenessCollection) { if (uniqueness.IsPreferred) { - return new List<ConceptTypeChild>(uniqueness.ConceptTypeChildCollection); + return uniqueness.ConceptTypeChildCollection; } } - foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType + ConceptTypeAssimilatesConceptType bestAssimilation = null; + ConceptTypeAssimilatesConceptType preferredForParent = null; + foreach (ConceptTypeAssimilatesConceptType assimilation in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) { - if (conceptTypeAssimilatesConceptType.IsPreferredForTarget) + if (assimilation.IsPreferredForTarget) { - List<ConceptTypeChild> prefferedConceptTypeChildrenList = new List<ConceptTypeChild>(1); - prefferedConceptTypeChildrenList.Add(conceptTypeAssimilatesConceptType); - return prefferedConceptTypeChildrenList; + bestAssimilation = assimilation; + break; } - } - foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType - in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptType)) - { - if (conceptTypeAssimilatesConceptType.IsPreferredForParent) + else if (preferredForParent == null && assimilation.IsPreferredForParent) { - List<ConceptTypeChild> prefferedConceptTypeChildrenList = new List<ConceptTypeChild>(1); - prefferedConceptTypeChildrenList.Add(conceptTypeAssimilatesConceptType); - return prefferedConceptTypeChildrenList; + preferredForParent = assimilation; + // Keep going to find the target preference if available } } + if (null != bestAssimilation || + null != (bestAssimilation = preferredForParent)) + { + return new ConceptTypeChild[] { bestAssimilation }; + } Debug.Fail("Couldn't find preferred identifier."); - return null; + return new ConceptTypeChild[0]; } /// <summary> @@ -834,15 +830,16 @@ Table table = TableIsPrimarilyForConceptType.GetTable(assimilation.AssimilatedConceptType); if (table != null) { - if (isPreferredForChildFound == false) + if (!isPreferredForChildFound) { + Store store = table.Store; if (assimilation.IsPreferredForParent) { - ReferenceConstraint referenceConstraint = new ReferenceConstraint(assimilation.Store, new PropertyAssignment[] { new PropertyAssignment(ReferenceConstraint.NameDomainPropertyId, assimilation.Name) }); + ReferenceConstraint referenceConstraint = new ReferenceConstraint(store, new PropertyAssignment[] { new PropertyAssignment(ReferenceConstraint.NameDomainPropertyId, assimilation.Name) }); TableContainsReferenceConstraint tableContainsReferenceConstraint = new TableContainsReferenceConstraint(TableIsPrimarilyForConceptType.GetTable(assimilation.AssimilatorConceptType), referenceConstraint); ReferenceConstraintTargetsTable referenceConstraintTargetsTable = new ReferenceConstraintTargetsTable(referenceConstraint, table); - UniquenessConstraint mappedConstraint = new UniquenessConstraint(assimilation.Store, new PropertyAssignment[] { new PropertyAssignment(UniquenessConstraint.NameDomainPropertyId, "Constraint") }); + UniquenessConstraint mappedConstraint = new UniquenessConstraint(store, new PropertyAssignment[] { new PropertyAssignment(UniquenessConstraint.NameDomainPropertyId, "Constraint") }); mappedConstraint.IsPrimary = true; List<Column> sourceColumns = ConceptTypeHasPrimaryIdentifierColumns(null, assimilation.Parent); @@ -856,155 +853,6 @@ TableIsPrimarilyForConceptType.GetTable(assimilation.AssimilatorConceptType).UniquenessConstraintCollection.Add(mappedConstraint); } - else if (assimilation.IsPreferredForTarget) - { - if (isPreferredForChildFound == false) - { - ConceptType parentConcept = assimilation.AssimilatorConceptType; - ConceptTypeAssimilatesConceptType assimilationPath = assimilation; - Table targetTable = null; - - while (targetTable == null) - { - targetTable = TableIsPrimarilyForConceptType.GetTable(parentConcept); - if (targetTable == null) - { - parentConcept = parentConcept.AssimilatorConceptTypeCollection[0]; - } - else - { - break; - } - } - - if (targetTable != null) - { - ReferenceConstraint referenceConstraint = new ReferenceConstraint(assimilation.Store, new PropertyAssignment[] { new PropertyAssignment(ReferenceConstraint.NameDomainPropertyId, assimilation.Name) }); - TableContainsReferenceConstraint tableContainsReferenceConstraint = new TableContainsReferenceConstraint(table, referenceConstraint); - ReferenceConstraintTargetsTable referenceConstraintTargetsTable = new ReferenceConstraintTargetsTable(referenceConstraint, targetTable); - - UniquenessConstraint mappedConstraint = new UniquenessConstraint(assimilation.Store, new PropertyAssignment[] { new PropertyAssignment(UniquenessConstraint.NameDomainPropertyId, "Constraint") }); - - // If it is prefered for target set the constraint as primary, otherwise perform the check in the defualt case. - mappedConstraint.IsPrimary = true; - - LinkedElementCollection<ConceptType> assimilations; - ConceptType conceptType = assimilation.AssimilatedConceptType; - List<Column> primaryIdentifierColumns = new List<Column>(); - - bool primaryIdentifierFound = false; - while ((assimilations = conceptType.AssimilatorConceptTypeCollection).Count != 0 && !primaryIdentifierFound) - { - conceptType = assimilations[0]; - - Table primaryTable = TableIsPrimarilyForConceptType.GetTable(conceptType); - - if (primaryTable != null) - { - foreach (UniquenessConstraint uniqueness in primaryTable.UniquenessConstraintCollection) - { - if (uniqueness.IsPrimary) - { - primaryIdentifierColumns.AddRange(uniqueness.ColumnCollection); - assimilation.IsMandatory = true; - primaryIdentifierFound = true; - } - } - - } - } - if (primaryIdentifierColumns.Count == 0) - { - primaryIdentifierColumns.AddRange(GetColumnsForConceptTypeChild(assimilation as ConceptTypeChild, new List<ConceptTypeChild>())); - primaryIdentifierFound = true; - } - - foreach (Column identifierColumn in primaryIdentifierColumns) - { - LinkedElementCollection<ConceptTypeChild> ctcpath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(identifierColumn); - if (primaryIdentifierFound == true) - { - foreach (ConceptTypeChild ctc in ctcpath) - { - ctc.IsMandatory = true; - } - } - Column clonedColumn = new Column(identifierColumn.Store, new PropertyAssignment[] { new PropertyAssignment(Column.NameDomainPropertyId, identifierColumn.Name) }); - List<ConceptTypeChild> clonedConceptTypeChildPath = new List<ConceptTypeChild>(ColumnHasConceptTypeChild.GetConceptTypeChildPath(identifierColumn)); - ColumnHasConceptTypeChild.GetConceptTypeChildPath(clonedColumn).Clear(); - ColumnHasConceptTypeChild.GetConceptTypeChildPath(clonedColumn).AddRange(clonedConceptTypeChildPath); - table.ColumnCollection.Add(clonedColumn); - ColumnReference relationship = new ColumnReference(clonedColumn, identifierColumn); - referenceConstraint.ColumnReferenceCollection.Add(relationship); - - mappedConstraint.ColumnCollection.Add(clonedColumn); - } - table.UniquenessConstraintCollection.Add(mappedConstraint); - } - isPreferredForChildFound = true; - } - } - //else if (assimilation.IsMandatory) - //{ - - // Table targetTable = null; - // ConceptType parentConcept = assimilation.AssimilatorConceptType; - // ConceptTypeAssimilatesConceptType assimilationPath = assimilation; - - // LinkedElementCollection<ConceptType> assimilations = null; - // ConceptType conceptType = assimilation.AssimilatedConceptType; - // List<Column> primaryIdentifierColumns = new List<Column>(); - - // bool primaryIdentifierFound = false; - - // while (targetTable == null && !primaryIdentifierFound) - // { - // targetTable = TableIsPrimarilyForConceptType.GetTable(parentConcept); - // if (targetTable == null) - // { - // parentConcept = parentConcept.AssimilatorConceptTypeCollection[0]; - // } - // else - // { - // foreach (UniquenessConstraint uniqueness in targetTable.UniquenessConstraintCollection) - // { - // if (uniqueness.IsPrimary) - // { - // primaryIdentifierColumns.AddRange(uniqueness.ColumnCollection); - // assimilation.IsMandatory = true; - // primaryIdentifierFound = true; - // } - // } - // } - // } - - // ReferenceConstraint referenceConstraint = new ReferenceConstraint(assimilation.Store, new PropertyAssignment[] { new PropertyAssignment(ReferenceConstraint.NameDomainPropertyId, assimilation.Name) }); - // TableContainsReferenceConstraint tableContainsReferenceConstraint = new TableContainsReferenceConstraint(TableIsPrimarilyForConceptType.GetTable(assimilation.AssimilatedConceptType), referenceConstraint); - // ReferenceConstraintTargetsTable referenceConstraintTargetsTable = new ReferenceConstraintTargetsTable(referenceConstraint, targetTable); - - - // if (primaryIdentifierColumns.Count == 0) - // { - // primaryIdentifierColumns.AddRange(GetColumnsForConceptTypeChild(assimilation as ConceptTypeChild, new List<ConceptTypeChild>())); - // } - - // foreach (Column identifierColumn in primaryIdentifierColumns) - // { - // Column clonedColumn = new Column(identifierColumn.Store, new PropertyAssignment[] { new PropertyAssignment(Column.NameDomainPropertyId, identifierColumn.Name) }); - // List<ConceptTypeChild> clonedConceptTypeChildPath = new List<ConceptTypeChild>(ColumnHasConceptTypeChild.GetConceptTypeChildPath(identifierColumn)); - - // foreach (ConceptTypeChild conceptTypeChild in clonedConceptTypeChildPath) - // { - // conceptTypeChild.IsMandatory = true; - // } - // ColumnHasConceptTypeChild.GetConceptTypeChildPath(clonedColumn).Clear(); - // ColumnHasConceptTypeChild.GetConceptTypeChildPath(clonedColumn).AddRange(clonedConceptTypeChildPath); - - // TableIsPrimarilyForConceptType.GetTable(assimilation.AssimilatedConceptType).ColumnCollection.Add(clonedColumn); - // ColumnReference relationship = new ColumnReference(clonedColumn, identifierColumn); - // referenceConstraint.ColumnReferenceCollection.Add(relationship); - // } - //} else { ConceptType parentConcept = assimilation.AssimilatorConceptType; @@ -1026,23 +874,33 @@ if (targetTable != null) { - ReferenceConstraint referenceConstraint = new ReferenceConstraint(assimilation.Store, new PropertyAssignment[] { new PropertyAssignment(ReferenceConstraint.NameDomainPropertyId, assimilation.Name) }); + ReferenceConstraint referenceConstraint = new ReferenceConstraint(store, new PropertyAssignment[] { new PropertyAssignment(ReferenceConstraint.NameDomainPropertyId, assimilation.Name) }); TableContainsReferenceConstraint tableContainsReferenceConstraint = new TableContainsReferenceConstraint(table, referenceConstraint); ReferenceConstraintTargetsTable referenceConstraintTargetsTable = new ReferenceConstraintTargetsTable(referenceConstraint, targetTable); - UniquenessConstraint mappedConstraint = new UniquenessConstraint(assimilation.Store, new PropertyAssignment[] { new PropertyAssignment(UniquenessConstraint.NameDomainPropertyId, "Constraint") }); + UniquenessConstraint mappedConstraint = new UniquenessConstraint(store, new PropertyAssignment[] { new PropertyAssignment(UniquenessConstraint.NameDomainPropertyId, "Constraint") }); - if (GetColumnsForConceptTypeChild(GetPreferredConceptTypeChildrenForConceptType(assimilation.AssimilatedConceptType)[0], new List<ConceptTypeChild>()) == null) + bool seenPrimary = false; + if (!assimilation.IsPreferredForTarget) { + GetColumnsForConceptTypeChild( + GetPreferredConceptTypeChildrenForConceptType(assimilation.AssimilatedConceptType)[0], + null, + delegate(InformationType childInformationType, Stack<ConceptTypeChild> childPathStack) + { + seenPrimary = true; + }); + } + if (!seenPrimary) + { mappedConstraint.IsPrimary = true; } LinkedElementCollection<ConceptType> assimilations; ConceptType conceptType = assimilation.AssimilatedConceptType; - List<Column> primaryIdentifierColumns = new List<Column>(); bool primaryIdentifierFound = false; - while ((assimilations = conceptType.AssimilatorConceptTypeCollection).Count != 0 && !primaryIdentifierFound) + while (!primaryIdentifierFound && (assimilations = conceptType.AssimilatorConceptTypeCollection).Count != 0) { conceptType = assimilations[0]; @@ -1054,42 +912,74 @@ { if (uniqueness.IsPrimary) { - primaryIdentifierColumns.AddRange(uniqueness.ColumnCollection); - assimilation.IsMandatory = true; + foreach (Column identifierColumn in uniqueness.ColumnCollection) + { + Column clonedColumn = new Column(store, new PropertyAssignment[] { new PropertyAssignment(Column.NameDomainPropertyId, identifierColumn.Name) }); + LinkedElementCollection<ConceptTypeChild> clonedColumnPath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(clonedColumn); + clonedColumnPath.Add(assimilation); + clonedColumnPath.AddRange(ColumnHasConceptTypeChild.GetConceptTypeChildPath(identifierColumn)); + new TableContainsColumn(table, clonedColumn); + new ReferenceConstraintContainsColumnReference(referenceConstraint, new ColumnReference(clonedColumn, identifierColumn)); + new UniquenessConstraintIncludesColumn(mappedConstraint, clonedColumn); + } primaryIdentifierFound = true; } } } } - if (primaryIdentifierColumns.Count == 0) + if (!primaryIdentifierFound) { - primaryIdentifierColumns.AddRange(GetColumnsForConceptTypeChild(assimilation as ConceptTypeChild, new List<ConceptTypeChild>())); - primaryIdentifierFound = true; - } - - foreach (Column identifierColumn in primaryIdentifierColumns) - { - LinkedElementCollection<ConceptTypeChild> ctcpath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(identifierColumn); - if (primaryIdentifierFound == true) - { - foreach (ConceptTypeChild ctc in ctcpath) + GetColumnsForConceptTypeChild( + assimilation, + new Stack<ConceptTypeChild>(), + delegate(InformationType childInformationType, Stack<ConceptTypeChild> childPathStack) { - ctc.IsMandatory = true; - } - } - Column clonedColumn = new Column(identifierColumn.Store, new PropertyAssignment[] { new PropertyAssignment(Column.NameDomainPropertyId, identifierColumn.Name) }); - List<ConceptTypeChild> clonedConceptTypeChildPath = new List<ConceptTypeChild>(ColumnHasConceptTypeChild.GetConceptTypeChildPath(identifierColumn)); - ColumnHasConceptTypeChild.GetConceptTypeChildPath(clonedColumn).Clear(); - ColumnHasConceptTypeChild.GetConceptTypeChildPath(clonedColumn).AddRange(clonedConceptTypeChildPath); - table.ColumnCollection.Add(clonedColumn); - ColumnReference relationship = new ColumnReference(clonedColumn, identifierColumn); - referenceConstraint.ColumnReferenceCollection.Add(relationship); + Column informationTypeColumn = new Column( + childInformationType.Store, + new PropertyAssignment[] { new PropertyAssignment(Column.NameDomainPropertyId, childInformationType.Name) }); + ConceptTypeChild[] pathArray = childPathStack.ToArray(); + int pathLength = pathArray.Length; + if (pathLength > 1) + { + Array.Reverse(pathArray); + } + ColumnHasConceptTypeChild.GetConceptTypeChildPath(informationTypeColumn).AddRange(pathArray); + new TableContainsColumn(table, informationTypeColumn); + new UniquenessConstraintIncludesColumn(mappedConstraint, informationTypeColumn); - mappedConstraint.ColumnCollection.Add(clonedColumn); - } - table.UniquenessConstraintCollection.Add(mappedConstraint); + // Create a column reference to the other column + foreach (Column possibleColumn in targetTable.ColumnCollection) + { + LinkedElementCollection<ConceptTypeChild> possiblePath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(possibleColumn); + int possiblePathCount = possiblePath.Count; + if (possiblePathCount < pathLength) + { + // We're looking for the end of the separated path to match + // the full possible path, and the Parent of the previous + // ConceptTypeChild in the separated path to match the + // concept type for the target table. + bool isMatch = true; + int sizeDifference = pathLength - possiblePathCount; + for (int i = possiblePathCount - 1; i >= 0; --i) + { + if (possiblePath[i] != pathArray[i + sizeDifference]) + { + isMatch = false; + break; + } + } + if (isMatch && pathArray[sizeDifference - 1].Parent == parentConcept) + { + new ReferenceConstraintContainsColumnReference(referenceConstraint, new ColumnReference(informationTypeColumn, possibleColumn)); + break; + } + } + } + }); + } + new TableContainsUniquenessConstraint(table, mappedConstraint); isPreferredForChildFound = true; } } @@ -1097,7 +987,7 @@ } else { - // If the seperation is further partitioned then it will not have a secondary child table, further assimilations or seperations are ok though. + // If the separation is further partitioned then it will not have a secondary child table, further assimilations or separations are ok though. ReadOnlyCollection<ConceptTypeAssimilatesConceptType> childAssimilations = ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(assimilation.AssimilatedConceptType); bool isPartitioned = false; foreach (ConceptTypeAssimilatesConceptType possiblePartition in childAssimilations) @@ -1110,11 +1000,10 @@ } if (isPartitioned) { - bool prefered = false; foreach (ConceptTypeAssimilatesConceptType partition in childAssimilations) { - DoSeparation(partition, ref prefered); - prefered = false; + bool preferred = false; + DoSeparation(partition, ref preferred); } } } @@ -1645,19 +1534,17 @@ { foreach (ConceptTypeChild conceptTypeChild in ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)) { - if (conceptTypeChild.GetType() == typeof(InformationType)) + ConceptTypeRelatesToConceptType relation; + if (null != (relation = conceptTypeChild as ConceptTypeRelatesToConceptType)) { - return null; + return relation; } - else if (conceptTypeChild.GetType() == typeof(ConceptTypeRelatesToConceptType)) + ConceptTypeAssimilatesConceptType assimilation = conceptTypeChild as ConceptTypeAssimilatesConceptType; + if (assimilation == null || // We have an InformationType + AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) == AssimilationAbsorptionChoice.Separate) { - return (ConceptTypeRelatesToConceptType)conceptTypeChild; + return null; } - else if (conceptTypeChild.GetType() == typeof(ConceptTypeAssimilatesConceptType)) - { - if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation((ConceptTypeAssimilatesConceptType)conceptTypeChild) == AssimilationAbsorptionChoice.Separate) - { return null; } - } } return null; } @@ -1670,32 +1557,56 @@ { foreach (Column column in table.ColumnCollection) { - CheckColumnConstraint(column); + CheckColumnConstraint(column, table); } } /// <summary> - /// CheckColumnConstraint looks at the the ConceptTypeChildPath for a column, setting the column to nullable when some point in the path is not manditory. + /// CheckColumnConstraint looks at the the ConceptTypeChildPath for a column, setting the column to nullable when some point in the path is not mandatory. /// </summary> private static void CheckColumnConstraint(Column column) { + CheckColumnConstraint(column, null); + } + /// <summary> + /// CheckColumnConstraint looks at the the ConceptTypeChildPath for a column, setting the column to nullable when some point in the path is not mandatory. + /// </summary> + private static void CheckColumnConstraint(Column column, Table table) + { bool allStepsMandatory = true; - foreach (ConceptTypeChild concept in ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)) + ConceptType lastTarget = null; + bool firstPass = true; + foreach (ConceptTypeChild child in ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)) { - if (!concept.IsMandatory) + if (!child.IsMandatory) { - // A ConceptTypeAssimilatesConceptType that is set to partition may(will) not be manditory, but the resulting columns should be, - // Do we wwant to perform a check on the ConceptTypeChild for that case here, or should we eariler change that Assimilation to a manditory one? - if (concept.GetType() == typeof(ConceptTypeAssimilatesConceptType) && AssimilationMapping.GetAbsorptionChoiceFromAssimilation(concept as ConceptTypeAssimilatesConceptType) == AssimilationAbsorptionChoice.Partition) + ConceptTypeAssimilatesConceptType assimilation = child as ConceptTypeAssimilatesConceptType; + if (assimilation != null) { + // The IsMandatory property applies when stepping parent-to-target, However, stepping target-to-parent + // is always considered mandatory. See if we're in this situation. + if (firstPass) + { + if (table == null) + { + table = column.Table; + } + lastTarget = TableIsPrimarilyForConceptType.GetConceptType(table); + } + if (lastTarget != null && + lastTarget == assimilation.Target) + { + lastTarget = assimilation.Parent; + firstPass = false; + continue; + } } - else - { - allStepsMandatory = false; - break; - } + allStepsMandatory = false; + break; } + lastTarget = child.Target as ConceptType; + firstPass = false; } column.IsNullable = !allStepsMandatory; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:51:26
|
Revision: 1139 http://orm.svn.sourceforge.net/orm/?rev=1139&view=rev Author: mcurland Date: 2007-09-20 13:51:23 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Display/accept entry of 'Unbounded' instead the underlying 0 value for the FrequencyConstraint.MaxFrequency property. fixes #341 Also added instructions to Note property description text. Modified Paths: -------------- trunk/ORMModel/ORMModel.csproj trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx trunk/ORMModel/ObjectModel/ORMCore.dsl trunk/ORMModel/ObjectModel/ORMModel.resx trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml Added Paths: ----------- trunk/ORMModel/ObjectModel/Design/Editors/FrequencyConstraintMaxPicker.cs trunk/ORMModel/ObjectModel/Design/FrequencyConstraintBoundConverter.cs Modified: trunk/ORMModel/ORMModel.csproj =================================================================== --- trunk/ORMModel/ORMModel.csproj 2007-09-20 20:48:24 UTC (rev 1138) +++ trunk/ORMModel/ORMModel.csproj 2007-09-20 20:51:23 UTC (rev 1139) @@ -417,6 +417,8 @@ </Compile> <Compile Include="Framework\Shell\DiagramMenuDisplay.cs" /> <Compile Include="Framework\Shell\SerializationEngine.cs" /> + <Compile Include="ObjectModel\Design\FrequencyConstraintBoundConverter.cs" /> + <Compile Include="ObjectModel\Design\Editors\FrequencyConstraintMaxPicker.cs" /> <Compile Include="ObjectModel\Design\ObjectificationRolePlayerPropertyDescriptor.cs" /> <Compile Include="ObjectModel\Design\Editors\ModelErrorDisplayFilterEditor.cs" /> <Compile Include="ObjectModel\ModelErrorDisplayFilter.cs" /> Added: trunk/ORMModel/ObjectModel/Design/Editors/FrequencyConstraintMaxPicker.cs =================================================================== --- trunk/ORMModel/ObjectModel/Design/Editors/FrequencyConstraintMaxPicker.cs (rev 0) +++ trunk/ORMModel/ObjectModel/Design/Editors/FrequencyConstraintMaxPicker.cs 2007-09-20 20:51:23 UTC (rev 1139) @@ -0,0 +1,69 @@ +#region Common Public License Copyright Notice +/**************************************************************************\ +* Neumont Object-Role Modeling Architect for Visual Studio * +* * +* Copyright \xA9 Neumont University. All rights reserved. * +* * +* The use and distribution terms for this software are covered by the * +* Common Public License 1.0 (http://opensource.org/licenses/cpl) which * +* can be found in the file CPL.txt at the root of this distribution. * +* By using this software in any fashion, you are agreeing to be bound by * +* the terms of this license. * +* * +* You must not remove this notice, or any other, from this software. * +\**************************************************************************/ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.Security.Permissions; +using Microsoft.VisualStudio.Modeling; +using Neumont.Tools.Modeling; +using Neumont.Tools.Modeling.Design; +using Neumont.Tools.ORM.ObjectModel; + +namespace Neumont.Tools.ORM.ObjectModel.Design +{ + #region FrequencyConstraintMaxPicker class + /// <summary> + /// An element picker to hide the fact that 0 means unbounded for the <see cref="FrequencyConstraint.MaxFrequency"/> property + /// </summary> + [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")] + public sealed class FrequencyConstraintMaxPicker : ElementPicker<FrequencyConstraintMaxPicker> + { + private int myStartValue; + /// <summary> + /// Returns the Unbounded value, as well as the current value if it is not unbounded + /// </summary> + protected sealed override IList GetContentList(ITypeDescriptorContext context, object value) + { + int intValue = (int)value; + myStartValue = intValue; + return (intValue == 0) ? + new string[]{ResourceStrings.FrequencyConstraintUnboundedMaxValueText} : + new string[]{intValue.ToString(CultureInfo.CurrentCulture), ResourceStrings.FrequencyConstraintUnboundedMaxValueText}; + } + /// <summary> + /// Translate a value back to the integer. This will be either the starting value or 0, meaning unbounded + /// </summary> + protected override object TranslateFromDisplayObject(int newIndex, object newObject) + { + return (newIndex == 1) ? 0 : myStartValue; + } + /// <summary> + /// Get the display object for the current value + /// </summary> + protected override object TranslateToDisplayObject(object initialObject, IList contentList) + { + int value = (int)initialObject; + return (value == 0 && contentList.Count == 2) ? contentList[1] : contentList[0]; + } + } + #endregion // FrequencyConstraintMaxPicker class +} Added: trunk/ORMModel/ObjectModel/Design/FrequencyConstraintBoundConverter.cs =================================================================== --- trunk/ORMModel/ObjectModel/Design/FrequencyConstraintBoundConverter.cs (rev 0) +++ trunk/ORMModel/ObjectModel/Design/FrequencyConstraintBoundConverter.cs 2007-09-20 20:51:23 UTC (rev 1139) @@ -0,0 +1,95 @@ +#region Common Public License Copyright Notice +/**************************************************************************\ +* Neumont Object-Role Modeling Architect for Visual Studio * +* * +* Copyright \xA9 Neumont University. All rights reserved. * +* * +* The use and distribution terms for this software are covered by the * +* Common Public License 1.0 (http://opensource.org/licenses/cpl) which * +* can be found in the file CPL.txt at the root of this distribution. * +* By using this software in any fashion, you are agreeing to be bound by * +* the terms of this license. * +* * +* You must not remove this notice, or any other, from this software. * +\**************************************************************************/ +#endregion + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.Security.Permissions; +using Microsoft.VisualStudio.Modeling; +using Microsoft.VisualStudio.Modeling.Design; +using Neumont.Tools.Modeling.Design; +using Neumont.Tools.ORM.ObjectModel; + +namespace Neumont.Tools.ORM.ObjectModel.Design +{ + /// <summary> + /// <see cref="TypeConverter"/> for <see cref="FrequencyConstraint.MinFrequency"/>s. + /// </summary> + [HostProtection(SecurityAction.LinkDemand, SharedState = true)] + public class FrequencyConstraintMinConverter : TypeConverter + { + /// <summary> + /// Standard override. Allow string conversion. + /// </summary> + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } + /// <summary> + /// Standard override. Map any value less than 1 to 1. + /// </summary> + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string stringValue = (value == null) ? "" : value.ToString(); + int result = int.Parse(stringValue); + return (result > 1) ? result : 1; + } + } + /// <summary> + /// <see cref="TypeConverter"/> for <see cref="FrequencyConstraint.MaxFrequency"/>s. + /// </summary> + [HostProtection(SecurityAction.LinkDemand, SharedState = true)] + public class FrequencyConstraintMaxConverter : TypeConverter + { + /// <summary> + /// Standard override. Allow string conversion. + /// </summary> + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } + /// <summary> + /// Standard override. Map any value less than 1 to 1. + /// </summary> + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string stringValue = (value == null) ? "" : value.ToString(); + if (0 == string.Compare(stringValue, ResourceStrings.FrequencyConstraintUnboundedMaxValueText, StringComparison.CurrentCultureIgnoreCase)) + { + return 0; + } + int result = int.Parse(stringValue); + return (result > 0) ? result : 0; + } + /// <summary> + /// Standard override. Show 'Unbounded' for the 0 value. + /// </summary> + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + int intValue = (int)value; + if (intValue == 0) + { + return ResourceStrings.FrequencyConstraintUnboundedMaxValueText; + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + } +} Modified: trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs =================================================================== --- trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs 2007-09-20 20:48:24 UTC (rev 1138) +++ trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs 2007-09-20 20:51:23 UTC (rev 1139) @@ -1384,7 +1384,8 @@ /// <summary> /// Gets or sets the value of NoteText domain property. - /// Description for Neumont.Tools.ORM.ObjectModel.ObjectType.Note + /// A note to associate with this ObjectType. To insert new lines, use Control-Enter + /// in the dropdown editor, or open the 'ORM Notes Editor' toolwindow. /// </summary> [global::System.ComponentModel.Editor(typeof(global::Neumont.Tools.Modeling.Design.MultilineTextEditor<global::Neumont.Tools.ORM.ObjectModel.Note>), typeof(global::System.Drawing.Design.UITypeEditor))] [global::System.ComponentModel.MergableProperty(false)] @@ -3086,7 +3087,8 @@ /// <summary> /// Gets or sets the value of NoteText domain property. - /// Description for Neumont.Tools.ORM.ObjectModel.FactType.Note + /// A note to associate with this FactType. To insert new lines, use Control-Enter + /// in the dropdown editor, or open the 'ORM Notes Editor' toolwindow. /// </summary> [global::System.ComponentModel.Editor(typeof(global::Neumont.Tools.Modeling.Design.MultilineTextEditor<global::Neumont.Tools.ORM.ObjectModel.Note>), typeof(global::System.Drawing.Design.UITypeEditor))] [global::System.ComponentModel.MergableProperty(false)] @@ -6247,6 +6249,7 @@ /// Gets or sets the value of MinFrequency domain property. /// Description for Neumont.Tools.ORM.ObjectModel.FrequencyConstraint.MinFrequency /// </summary> + [global::System.ComponentModel.TypeConverter(typeof(global::Neumont.Tools.ORM.ObjectModel.Design.FrequencyConstraintMinConverter))] [DslDesign::DisplayNameResource("Neumont.Tools.ORM.ObjectModel.FrequencyConstraint/MinFrequency.DisplayName", typeof(global::Neumont.Tools.ORM.ObjectModel.ORMCoreDomainModel), "Neumont.Tools.ORM.GeneratedCode.CoreDomainModelResx")] [DslDesign::DescriptionResource("Neumont.Tools.ORM.ObjectModel.FrequencyConstraint/MinFrequency.Description", typeof(global::Neumont.Tools.ORM.ObjectModel.ORMCoreDomainModel), "Neumont.Tools.ORM.GeneratedCode.CoreDomainModelResx")] [global::System.ComponentModel.DefaultValue(1)] @@ -6335,6 +6338,8 @@ /// Gets or sets the value of MaxFrequency domain property. /// Description for Neumont.Tools.ORM.ObjectModel.FrequencyConstraint.MaxFrequency /// </summary> + [global::System.ComponentModel.Editor(typeof(global::Neumont.Tools.ORM.ObjectModel.Design.FrequencyConstraintMaxPicker), typeof(global::System.Drawing.Design.UITypeEditor))] + [global::System.ComponentModel.TypeConverter(typeof(global::Neumont.Tools.ORM.ObjectModel.Design.FrequencyConstraintMaxConverter))] [DslDesign::DisplayNameResource("Neumont.Tools.ORM.ObjectModel.FrequencyConstraint/MaxFrequency.DisplayName", typeof(global::Neumont.Tools.ORM.ObjectModel.ORMCoreDomainModel), "Neumont.Tools.ORM.GeneratedCode.CoreDomainModelResx")] [DslDesign::DescriptionResource("Neumont.Tools.ORM.ObjectModel.FrequencyConstraint/MaxFrequency.Description", typeof(global::Neumont.Tools.ORM.ObjectModel.ORMCoreDomainModel), "Neumont.Tools.ORM.GeneratedCode.CoreDomainModelResx")] [global::System.ComponentModel.DefaultValue(2)] @@ -13876,7 +13881,8 @@ /// <summary> /// Gets or sets the value of Text domain property. - /// Description for Neumont.Tools.ORM.ObjectModel.Note.Note + /// The note contents. To insert new lines, use Control-Enter in the dropdown + /// editor, or open the 'ORM Notes Editor' toolwindow. /// </summary> [global::System.ComponentModel.Editor(typeof(global::Neumont.Tools.Modeling.Design.MultilineTextEditor<global::Neumont.Tools.ORM.ObjectModel.Note>), typeof(global::System.Drawing.Design.UITypeEditor))] [global::System.ComponentModel.MergableProperty(false)] Modified: trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx =================================================================== --- trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx 2007-09-20 20:48:24 UTC (rev 1138) +++ trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx 2007-09-20 20:51:23 UTC (rev 1139) @@ -278,7 +278,7 @@ <comment>DisplayName for DomainProperty 'IsExternal' on DomainClass 'ObjectType'</comment> </data> <data name="Neumont.Tools.ORM.ObjectModel.ObjectType/NoteText.Description" xml:space="preserve"> - <value>Description for Neumont.Tools.ORM.ObjectModel.ObjectType.Note</value> + <value>A note to associate with this ObjectType. To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' toolwindow.</value> <comment>Description for DomainProperty 'NoteText' on DomainClass 'ObjectType'</comment> </data> <data name="Neumont.Tools.ORM.ObjectModel.ObjectType/NoteText.DisplayName" xml:space="preserve"> @@ -398,7 +398,7 @@ <comment>DisplayName for DomainProperty 'IsExternal' on DomainClass 'FactType'</comment> </data> <data name="Neumont.Tools.ORM.ObjectModel.FactType/NoteText.Description" xml:space="preserve"> - <value>Description for Neumont.Tools.ORM.ObjectModel.FactType.Note</value> + <value>A note to associate with this FactType. To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' toolwindow.</value> <comment>Description for DomainProperty 'NoteText' on DomainClass 'FactType'</comment> </data> <data name="Neumont.Tools.ORM.ObjectModel.FactType/NoteText.DisplayName" xml:space="preserve"> @@ -1550,7 +1550,7 @@ <comment>DisplayName for DomainClass 'Note'</comment> </data> <data name="Neumont.Tools.ORM.ObjectModel.Note/Text.Description" xml:space="preserve"> - <value>Description for Neumont.Tools.ORM.ObjectModel.Note.Note</value> + <value>The note contents. To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' toolwindow.</value> <comment>Description for DomainProperty 'Text' on DomainClass 'Note'</comment> </data> <data name="Neumont.Tools.ORM.ObjectModel.Note/Text.DisplayName" xml:space="preserve"> Modified: trunk/ORMModel/ObjectModel/ORMCore.dsl =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.dsl 2007-09-20 20:48:24 UTC (rev 1138) +++ trunk/ORMModel/ObjectModel/ORMCore.dsl 2007-09-20 20:51:23 UTC (rev 1139) @@ -202,7 +202,7 @@ <ExternalTypeMoniker Name="/System/Boolean"/> </Type> </DomainProperty> - <DomainProperty Name="NoteText" DefaultValue="" DisplayName="Note" Id="17C4E23D-CA49-4329-982F-48F4EFCA23BD" Kind="CustomStorage"> + <DomainProperty Name="NoteText" DefaultValue="" DisplayName="Note" Description="A note to associate with this ObjectType. To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' toolwindow." Id="17C4E23D-CA49-4329-982F-48F4EFCA23BD" Kind="CustomStorage"> <Attributes> <ClrAttribute Name="global::System.ComponentModel.Editor"> <Parameters> @@ -328,7 +328,7 @@ <ExternalTypeMoniker Name="/System/Boolean"/> </Type> </DomainProperty> - <DomainProperty Name="NoteText" DefaultValue="" DisplayName="Note" Id="AF6200B1-068D-434A-98D3-44E872B921BD" Kind="CustomStorage"> + <DomainProperty Name="NoteText" DefaultValue="" DisplayName="Note" Description="A note to associate with this FactType. To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' toolwindow." Id="AF6200B1-068D-434A-98D3-44E872B921BD" Kind="CustomStorage"> <Attributes> <ClrAttribute Name="global::System.ComponentModel.Editor"> <Parameters> @@ -593,11 +593,31 @@ </BaseClass> <Properties> <DomainProperty Name="MinFrequency" DefaultValue="1" DisplayName="MinFrequency" Id="2D48D3CA-564D-459E-A701-4209A12C4783"> + <Attributes> + <ClrAttribute Name="global::System.ComponentModel.TypeConverter"> + <Parameters> + <AttributeParameter Value="typeof(global::Neumont.Tools.ORM.ObjectModel.Design.FrequencyConstraintMinConverter)"/> + </Parameters> + </ClrAttribute> + </Attributes> <Type> <ExternalTypeMoniker Name="/System/Int32"/> </Type> </DomainProperty> <DomainProperty Name="MaxFrequency" DefaultValue="2" DisplayName="MaxFrequency" Id="F46D9200-3602-435C-B852-C53BE10D99C6"> + <Attributes> + <ClrAttribute Name="global::System.ComponentModel.Editor"> + <Parameters> + <AttributeParameter Value="typeof(global::Neumont.Tools.ORM.ObjectModel.Design.FrequencyConstraintMaxPicker)"/> + <AttributeParameter Value="typeof(global::System.Drawing.Design.UITypeEditor)"/> + </Parameters> + </ClrAttribute> + <ClrAttribute Name="global::System.ComponentModel.TypeConverter"> + <Parameters> + <AttributeParameter Value="typeof(global::Neumont.Tools.ORM.ObjectModel.Design.FrequencyConstraintMaxConverter)"/> + </Parameters> + </ClrAttribute> + </Attributes> <Type> <ExternalTypeMoniker Name="/System/Int32"/> </Type> @@ -1334,7 +1354,7 @@ <DomainClassMoniker Name="ORMModelElement"/> </BaseClass> <Properties> - <DomainProperty Name="Text" DefaultValue="" DisplayName="Note" Id="0EF3BC12-45FF-46A8-B325-CDFCC105A1E1"> + <DomainProperty Name="Text" DefaultValue="" Description="The note contents. To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' toolwindow." DisplayName="Note" Id="0EF3BC12-45FF-46A8-B325-CDFCC105A1E1"> <Attributes> <ClrAttribute Name="global::System.ComponentModel.Editor"> <Parameters> Modified: trunk/ORMModel/ObjectModel/ORMModel.resx =================================================================== --- trunk/ORMModel/ObjectModel/ORMModel.resx 2007-09-20 20:48:24 UTC (rev 1138) +++ trunk/ORMModel/ObjectModel/ORMModel.resx 2007-09-20 20:51:23 UTC (rev 1139) @@ -163,6 +163,10 @@ <value>Remove Implied Internal Uniqueness Constraints</value> <comment>The name of the transaction that auto-fixes implied and duplicate internal constraints.</comment> </data> + <data name="FrequencyConstraint.UnboundedMaxValueText" xml:space="preserve"> + <value>Unbounded</value> + <comment>Text used in the dropdown editor and type converter for the frequency constraint max value. Correspond to the 0 value in the object model.</comment> + </data> <data name="ImplicitBooleanValueType.PropertyRestriction" xml:space="preserve"> <value>The modification of the IsImplicitBooleanValue property on a ValueType is not allowed.</value> <comment>Error message for when a user attempts to modify properties on an Implicit Boolean ValueType</comment> Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2007-09-20 20:48:24 UTC (rev 1138) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2007-09-20 20:51:23 UTC (rev 1139) @@ -2268,6 +2268,14 @@ return ResourceStrings.GetString(ResourceManagers.Model, "ImplicitBooleanValueType.NoReadingFormatString"); } } + /// <summary>Text used in the dropdown editor and type converter for the frequency constraint max value. Correspond to the 0 value in the object model.</summary> + public static string FrequencyConstraintUnboundedMaxValueText + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "FrequencyConstraint.UnboundedMaxValueText"); + } + } /// <summary>Description for target HtmlReport customizations. Displays in the verbalization customizations dropdown in the options page.</summary> public static string VerbalizationTargetHtmlReportDisplayName { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2007-09-20 20:48:24 UTC (rev 1138) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2007-09-20 20:51:23 UTC (rev 1139) @@ -426,6 +426,7 @@ <ResourceString name="ImplicitBooleanValueTypeRestriction" model="Model" resourceName="ImplicitBooleanValueType.Restriction"/> <ResourceString name="ImplicitBooleanValueTypePropertyRestriction" model="Model" resourceName="ImplicitBooleanValueType.PropertyRestriction"/> <ResourceString name="ImplicitBooleanValueTypeNoReadingFormatString" model="Model" resourceName="ImplicitBooleanValueType.NoReadingFormatString"/> + <ResourceString name="FrequencyConstraintUnboundedMaxValueText" model="Model" resourceName="FrequencyConstraint.UnboundedMaxValueText"/> <ResourceString name="VerbalizationTargetHtmlReportDisplayName" model="Model" resourceName="VerbalizationTarget.HtmlReport.DisplayName"/> <ResourceString name="VerbalizationTargetHtmlReportCommandName" model="Model" resourceName="VerbalizationTarget.HtmlReport.CommandName"/> <ResourceString name="VerbalizationTargetVerbalizationBrowserDisplayName" model="Model" resourceName="VerbalizationTarget.VerbalizationBrowser.DisplayName"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:48:20
|
Revision: 1138 http://orm.svn.sourceforge.net/orm/?rev=1138&view=rev Author: mcurland Date: 2007-09-20 13:48:24 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Block property descriptor changes on model-browser selected roles of unary fact types. refs #296 Fixed warning introduced in [1137]. refs #305 Modified Paths: -------------- trunk/ORMModel/ObjectModel/Design/RoleTypeDescriptor.cs trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs Modified: trunk/ORMModel/ObjectModel/Design/RoleTypeDescriptor.cs =================================================================== --- trunk/ORMModel/ObjectModel/Design/RoleTypeDescriptor.cs 2007-09-20 20:46:20 UTC (rev 1137) +++ trunk/ORMModel/ObjectModel/Design/RoleTypeDescriptor.cs 2007-09-20 20:48:24 UTC (rev 1138) @@ -75,10 +75,24 @@ /// </summary> protected override bool IsPropertyDescriptorReadOnly(ElementPropertyDescriptor propertyDescriptor) { - if (propertyDescriptor.DomainPropertyInfo.Id == Role.ValueRangeTextDomainPropertyId) + Guid propertyId = propertyDescriptor.DomainPropertyInfo.Id; + if (propertyId == Role.ValueRangeTextDomainPropertyId) { return !ModelElement.IsValueRole; } + else if (propertyId == Role.IsMandatoryDomainPropertyId || + propertyId == Role.RolePlayerDisplayDomainPropertyId || + propertyId == Role.MandatoryConstraintModalityDomainPropertyId || + propertyId == Role.MultiplicityDomainPropertyId) + { + Role role = ModelElement; + if (role is SubtypeMetaRole || + role is SupertypeMetaRole || + null != role.FactType.UnaryRole) + { + return true; + } + } return base.IsPropertyDescriptorReadOnly(propertyDescriptor); } } Modified: trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs =================================================================== --- trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs 2007-09-20 20:46:20 UTC (rev 1137) +++ trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs 2007-09-20 20:48:24 UTC (rev 1138) @@ -196,7 +196,7 @@ return; } const int OrcasMajorVersionNumber = 9; - const string TemplateWizardAssemblyName = "Microsoft.VisualStudio.TemplateWizard"; + // UNDONE: See assert where this is used const string TemplateWizardAssemblyName = "Microsoft.VisualStudio.TemplateWizard"; const string SuppressOpeningItems = "$__suppress_opening_items__$"; bool? templateWizardIsOrcasOrLater = TemplateWizardIsOrcasOrLater; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:46:19
|
Revision: 1137 http://orm.svn.sourceforge.net/orm/?rev=1137&view=rev Author: mcurland Date: 2007-09-20 13:46:20 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Do some additional work on the database importer. The import works fine for a DB with one schema, but does not allow tables from multiple schemas to be imported, which is a fundamental issue that will take some redesign. Also, our layout on import is not looking very good. Decline adding to setup for now until these issues are fixed. refs #305 Modified Paths: -------------- trunk/ORMModel/Shell/ORMGeneralTemplateWizard.cs trunk/ORMModel/Shell/PackageResources/PackageResources.cs trunk/ORMModel/Shell/PackageResources/VSPackage.resx trunk/Tools/DatabaseImport/Install.bat trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs trunk/Tools/DatabaseImport/SqlServer2005DcilSchemaProvider.cs Added Paths: ----------- trunk/Tools/DatabaseImport/ProjectItems/ trunk/Tools/DatabaseImport/ProjectItems/CSharp.zip trunk/Tools/DatabaseImport/ProjectItems/General.zip trunk/Tools/DatabaseImport/ProjectItems/JSharp.zip trunk/Tools/DatabaseImport/ProjectItems/VisualBasic.zip trunk/Tools/DatabaseImport/ProjectItems/VisualC.zip trunk/Tools/DatabaseImport/ProjectItems/Web/ trunk/Tools/DatabaseImport/ProjectItems/Web/CSharp.zip trunk/Tools/DatabaseImport/ProjectItems/Web/JSharp.zip trunk/Tools/DatabaseImport/ProjectItems/Web/VisualBasic.zip Removed Paths: ------------- trunk/Tools/DatabaseImport/OrmDatabaseImportTemplate.zip Modified: trunk/ORMModel/Shell/ORMGeneralTemplateWizard.cs =================================================================== --- trunk/ORMModel/Shell/ORMGeneralTemplateWizard.cs 2007-09-20 20:41:26 UTC (rev 1136) +++ trunk/ORMModel/Shell/ORMGeneralTemplateWizard.cs 2007-09-20 20:46:20 UTC (rev 1137) @@ -37,6 +37,7 @@ // Given that we can't make a non-nested class 'private', 'internal' is at least better than 'public'. internal sealed class ORMGeneralTemplateWizard : IWizard { + // This code is duplicated in Tools/DatabaseImport/ORMDatabaseImportWizard.cs (ORMDatabaseImportGeneralProjectWizard class) private static bool? TemplateWizardIsOrcasOrLater; /// <summary> Modified: trunk/ORMModel/Shell/PackageResources/PackageResources.cs =================================================================== --- trunk/ORMModel/Shell/PackageResources/PackageResources.cs 2007-09-20 20:41:26 UTC (rev 1136) +++ trunk/ORMModel/Shell/PackageResources/PackageResources.cs 2007-09-20 20:46:20 UTC (rev 1137) @@ -21,6 +21,11 @@ public const int AboutBoxIcon = 110; public const int ORMFileIcon = 111; + // Favor for the DatabaseImport project, the resources + // need to be in a package. + // public const int ORMFileDBImportDisplayName = 112; + // public const int ORMFileDBImportDescription = 113; + public const int ToolWindowIcons = 125; public const int PackageLoadKey = 150; Modified: trunk/ORMModel/Shell/PackageResources/VSPackage.resx =================================================================== --- trunk/ORMModel/Shell/PackageResources/VSPackage.resx 2007-09-20 20:41:26 UTC (rev 1136) +++ trunk/ORMModel/Shell/PackageResources/VSPackage.resx 2007-09-20 20:46:20 UTC (rev 1137) @@ -106,6 +106,14 @@ <value>../../Resources/ORM.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <comment>PackageResources.Id.ORMFileIcon</comment> </data> + <data name="112"> + <value>Object-Role Modeling (DB Import)</value> + <comment>PackageResources.Id.ORMFileDBImportDisplayName</comment> + </data> + <data name="113"> + <value>Object-Role Modeling File for Neumont ORM Architect (Reverse Engineer from Database)</value> + <comment>PackageResources.Id.ORMFileDBImportDescription</comment> + </data> <data name="125" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>../../Resources/ToolWindowIcons.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <comment>PackageResources.Id.ToolWindowIcons and IDB_TOOLWINDOWICONS</comment> Modified: trunk/Tools/DatabaseImport/Install.bat =================================================================== --- trunk/Tools/DatabaseImport/Install.bat 2007-09-20 20:41:26 UTC (rev 1136) +++ trunk/Tools/DatabaseImport/Install.bat 2007-09-20 20:46:20 UTC (rev 1137) @@ -3,4 +3,5 @@ SET RootDir=%~dp0. CALL "%RootDir%\..\..\SetupEnvironment.bat" %* -XCOPY /Y /D /V /Q "%RootDir%\OrmDatabaseImportTemplate.zip" "%VSItemTemplatesDir%\CSharp\" +FOR %%A IN ("%RootDir%\ProjectItems\*.zip") DO ECHO F | XCOPY /Y /D /V /Q "%%~fA" "%VSItemTemplatesDir%\%%~nA\ORMModelFromDatabase.zip" +FOR %%A IN ("%RootDir%\ProjectItems\Web\*.zip") DO ECHO F | XCOPY /Y /D /V /Q "%%~fA" "%VSItemTemplatesDir%\Web\%%~nA\ORMModelFromDatabase.zip" Modified: trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs =================================================================== --- trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs 2007-09-20 20:41:26 UTC (rev 1136) +++ trunk/Tools/DatabaseImport/ORMDatabaseImportWizard.cs 2007-09-20 20:46:20 UTC (rev 1137) @@ -3,6 +3,7 @@ using System.Data; using System.Diagnostics; using System.Text; +using Microsoft.VisualStudio; using Microsoft.VisualStudio.TemplateWizard; using Microsoft.VisualStudio.Data; using Microsoft.VisualStudio.Shell; @@ -20,28 +21,56 @@ /// <summary> /// Wizard interface used when loading a DcilREFromDB template /// </summary> + [CLSCompliant(false)] + [TemplateWizardDisallowUserTemplatesSecurity(true)] public class ORMDatabaseImportWizard : IWizard { #region Member variables - private bool myAddToProject = true; + private bool myAddToProject = false; #endregion // Member variables #region IWizard Members + /// <summary> + /// Implements <see cref="IWizard.BeforeOpeningFile"/> + /// </summary> + protected void BeforeOpeningFile(EnvDTE.ProjectItem projectItem) + { + } void IWizard.BeforeOpeningFile(EnvDTE.ProjectItem projectItem) { + BeforeOpeningFile(projectItem); } + /// <summary> + /// Implements <see cref="IWizard.ProjectFinishedGenerating"/> + /// </summary> + protected void ProjectFinishedGenerating(EnvDTE.Project project) + { + } void IWizard.ProjectFinishedGenerating(EnvDTE.Project project) { + ProjectFinishedGenerating(project); } + /// <summary> + /// Implements <see cref="IWizard.ProjectItemFinishedGenerating"/> + /// </summary> + protected void ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem) + { + } void IWizard.ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem) { - + ProjectItemFinishedGenerating(projectItem); + } + /// <summary> + /// Implements <see cref="IWizard.RunFinished"/> + /// </summary> + protected void RunFinished() + { } - void IWizard.RunFinished() { + RunFinished(); } /// <summary> @@ -55,7 +84,10 @@ return ((provider != null) ? provider.GetService(serviceType) as T : null) ?? Package.GetGlobalService(serviceType) as T; } - void IWizard.RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) + /// <summary> + /// Implements <see cref="IWizard.RunStarted"/> + /// </summary> + protected void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) { IOleServiceProvider oleServiceProvider = automationObject as IOleServiceProvider; ServiceProvider serviceProvider = (oleServiceProvider != null) ? new ServiceProvider(oleServiceProvider) : null; @@ -120,14 +152,189 @@ replacementsDictionary.Add("$DcilFile$", replacementString); } } - } + myAddToProject = true; + } } + void IWizard.RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) + { + RunStarted(automationObject, replacementsDictionary, runKind, customParams); + } - bool IWizard.ShouldAddProjectItem(string filePath) + /// <summary> + /// Implements <see cref="IWizard.ShouldAddProjectItem"/> + /// </summary> + protected bool ShouldAddProjectItem(string filePath) { return myAddToProject; } - + bool IWizard.ShouldAddProjectItem(string filePath) + { + return ShouldAddProjectItem(filePath); + } #endregion } + // Following code is lifted directly from ORMModel/Shell/ORMGeneralTemplateWizard.cs + + /// <summary> + /// Works around Visual Studio bugs in order to allow <c>.vstemplate</c> files + /// to be used for the "<c>General</c>" <c>ProjectType</c>. + /// </summary> + [CLSCompliant(false)] + public class ORMDatabaseImportGeneralProjectWizard : ORMDatabaseImportWizard, IWizard + { + private static bool? TemplateWizardIsOrcasOrLater; + + /// <summary> + /// Prevents the pre-Orcas version of <c>Microsoft.VisualStudio.TemplateWizard.Wizard</c> from crashing in <c>OpenNotedItems</c>. + /// </summary> + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + protected new void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) + { + base.RunStarted(automationObject, replacementsDictionary, runKind, customParams); + if (!base.ShouldAddProjectItem(null)) + { + return; + } + const int OrcasMajorVersionNumber = 9; + const string TemplateWizardAssemblyName = "Microsoft.VisualStudio.TemplateWizard"; + const string SuppressOpeningItems = "$__suppress_opening_items__$"; + + bool? templateWizardIsOrcasOrLater = TemplateWizardIsOrcasOrLater; + + // If we haven't yet determined whether we are being called by the pre-Orcas version of TemplateWizard or not, do so now. + if (!templateWizardIsOrcasOrLater.HasValue) + { + System.Reflection.Assembly callingAssembly = System.Reflection.Assembly.GetCallingAssembly(); + + // UNDONE: This is asserting at this point, figure out how to determine if we're Whidbey or Orcas + //Debug.Assert(callingAssembly != null && callingAssembly.FullName.StartsWith(TemplateWizardAssemblyName, StringComparison.Ordinal)); + + // If for any reason we can't tell what version we're running under, we assume it is pre-Orcas. + templateWizardIsOrcasOrLater = TemplateWizardIsOrcasOrLater = + (callingAssembly != null && (callingAssembly.GetName().Version.Major >= OrcasMajorVersionNumber)); + } + + if (templateWizardIsOrcasOrLater.GetValueOrDefault()) + { + // The Orcas version of TemplateWizard correctly checks Project.FullName for null / empty string before + // trying to create a Uri from it. Therefore, this workaround is only needed for pre-Orcas versions. + return; + } + + Debug.Assert(runKind == WizardRunKind.AsNewItem); + + if (replacementsDictionary == null) + { + // If we don't have a replacements dictionary, we can't do anything anyway, so just bail out. + return; + } + + if (!replacementsDictionary.ContainsKey(SuppressOpeningItems)) + { + // The value that we add doesn't really matter (only the key does), + // but just in case they start doing anything with it, we'll use "true". + replacementsDictionary.Add(SuppressOpeningItems, "true"); + } + } + void IWizard.RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) + { + RunStarted(automationObject, replacementsDictionary, runKind, customParams); + } + + /// <summary> + /// Ensures that only the file name portion of the new <see cref="ProjectItem"/>'s path is used as the + /// title for the document window. + /// </summary> + protected new void ProjectItemFinishedGenerating(ProjectItem projectItem) + { + base.ProjectItemFinishedGenerating(projectItem); + + // UNDONE: This may or may not be needed for Orcas. This needs to be tested, and if it is not needed, + // the following code block should be uncommented. + //Debug.Assert(TemplateWizardIsOrcasOrLater.HasValue, "RunStarted should have been called before ProjectItemFinishedGenerating is called."); + //if (TemplateWizardIsOrcasOrLater.GetValueOrDefault()) + //{ + // return; + //} + + if (projectItem == null) + { + throw new ArgumentNullException("projectItem"); + } + + DTE application = projectItem.DTE; + if (application == null) + { + // If we can't get the DTE, just bail out. + return; + } + + Document document = projectItem.Document; + if (document == null) + { + // At the point this is called, the ProjectItem seems to not have the Document associated with it yet. + // In that case, we need to look through the documents to find it. We'll try ActiveDocument first... + document = application.ActiveDocument; + if (document.ProjectItem != projectItem) + { + document = null; + Documents documents = application.Documents; + if (documents != null) + { + foreach (Document potentialDocument in documents) + { + if (potentialDocument.ProjectItem == projectItem) + { + document = potentialDocument; + break; + } + } + } + } + } + + if (document != null) + { + IOleServiceProvider oleServiceProvider = application as IOleServiceProvider; + if (oleServiceProvider == null) + { + // If we can't get an IOleServiceProvider, just bail out. + return; + } + + IVsUIHierarchy uiHierarchy; + uint itemId; + IVsWindowFrame windowFrame; + bool documentIsOpen = VsShellUtilities.IsDocumentOpen(new ServiceProvider(oleServiceProvider), document.FullName, Guid.Empty, out uiHierarchy, out itemId, out windowFrame); + Debug.Assert(documentIsOpen); + + if (windowFrame != null) + { + object pVar; + ErrorHandler.ThrowOnFailure(uiHierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_Caption, out pVar)); + string caption = pVar as string; + if (!string.IsNullOrEmpty(caption)) + { + try + { + caption = Path.GetFileName(caption); + } + catch (ArgumentException) + { + // Ignore any ArgumentException (which can occur if the caption contains characters invalid in a path). + return; + } + // Set the new caption on the backend document. + ErrorHandler.ThrowOnFailure(uiHierarchy.SetProperty(itemId, (int)__VSHPROPID.VSHPROPID_Caption, caption)); + // Set the new caption on the window. + ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID.VSFPROPID_OwnerCaption, caption)); + } + } + } + } + void IWizard.ProjectItemFinishedGenerating(ProjectItem projectItem) + { + ProjectItemFinishedGenerating(projectItem); + } + } } Deleted: trunk/Tools/DatabaseImport/OrmDatabaseImportTemplate.zip =================================================================== (Binary files differ) Added: trunk/Tools/DatabaseImport/ProjectItems/CSharp.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/CSharp.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Tools/DatabaseImport/ProjectItems/General.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/General.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Tools/DatabaseImport/ProjectItems/JSharp.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/JSharp.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Tools/DatabaseImport/ProjectItems/VisualBasic.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/VisualBasic.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Tools/DatabaseImport/ProjectItems/VisualC.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/VisualC.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Tools/DatabaseImport/ProjectItems/Web/CSharp.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/Web/CSharp.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Tools/DatabaseImport/ProjectItems/Web/JSharp.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/Web/JSharp.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Tools/DatabaseImport/ProjectItems/Web/VisualBasic.zip =================================================================== (Binary files differ) Property changes on: trunk/Tools/DatabaseImport/ProjectItems/Web/VisualBasic.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/Tools/DatabaseImport/SqlServer2005DcilSchemaProvider.cs =================================================================== --- trunk/Tools/DatabaseImport/SqlServer2005DcilSchemaProvider.cs 2007-09-20 20:41:26 UTC (rev 1136) +++ trunk/Tools/DatabaseImport/SqlServer2005DcilSchemaProvider.cs 2007-09-20 20:46:20 UTC (rev 1137) @@ -143,15 +143,12 @@ _conn.Open(); IDbCommand cmd = _conn.CreateCommand(); cmd.CommandType = CommandType.Text; - string commandText = "SELECT COLUMN_NAME, IS_NULLABLE, COLUMNPROPERTY(OBJECT_ID(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IS_IDENTITY, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COALESCE(NUMERIC_PRECISION, DATETIME_PRECISION), NUMERIC_SCALE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME IS NOT NULL"; - if (!String.IsNullOrEmpty(schemaName)) - { - commandText += " AND TABLE_SCHEMA = '" + schemaName + "'"; - } - if (!String.IsNullOrEmpty(tableName)) - { - commandText += " AND TABLE_NAME = '" + tableName + "'"; - } + bool haveSchema = !string.IsNullOrEmpty(schemaName); + string commandText = "SELECT COLUMN_NAME, IS_NULLABLE, COLUMNPROPERTY(OBJECT_ID(" + + (haveSchema ? "TABLE_SCHEMA + '.' + " : "") + + "TABLE_NAME), COLUMN_NAME, 'IsIdentity') IS_IDENTITY, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COALESCE(NUMERIC_PRECISION, DATETIME_PRECISION), NUMERIC_SCALE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME IS NOT NULL" + + (haveSchema ? " AND TABLE_SCHEMA = '" + schemaName + "'" : "") + + " AND TABLE_NAME = '" + tableName + "'"; cmd.CommandText = commandText; using (IDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:39:42
|
Revision: 1135 http://orm.svn.sourceforge.net/orm/?rev=1135&view=rev Author: mcurland Date: 2007-09-20 13:39:17 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Added file missed in [1174]. refs #167 refs #328 Modified Paths: -------------- trunk/XML/DILtoSQL/DDILtoPostgreSQL.xslt Added Paths: ----------- trunk/XML/DILtoSQL/TruthValueTestRemover.xslt Modified: trunk/XML/DILtoSQL/DDILtoPostgreSQL.xslt =================================================================== (Binary files differ) Added: trunk/XML/DILtoSQL/TruthValueTestRemover.xslt =================================================================== --- trunk/XML/DILtoSQL/TruthValueTestRemover.xslt (rev 0) +++ trunk/XML/DILtoSQL/TruthValueTestRemover.xslt 2007-09-20 20:39:17 UTC (rev 1135) @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright © Neumont University. All rights reserved. + + This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +--> +<!-- Contributors: Kevin M. Owen --> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:exsl="http://exslt.org/common" + xmlns:dml="http://schemas.orm.net/DIL/DMIL" + xmlns:dms="http://schemas.orm.net/DIL/DILMS" + xmlns:dep="http://schemas.orm.net/DIL/DILEP" + xmlns:ddt="http://schemas.orm.net/DIL/DILDT" + xmlns:dil="http://schemas.orm.net/DIL/DIL" + xmlns:ddl="http://schemas.orm.net/DIL/DDIL" + extension-element-prefixes="exsl"> + + <xsl:output method="xml" encoding="utf-8" media-type="text/xml" indent="yes"/> + <xsl:strip-space elements="*"/> + + <xsl:template match="*" mode="TruthValueTestRemover"> + <xsl:copy> + <xsl:copy-of select="@*"/> + <xsl:apply-templates mode="TruthValueTestRemover"/> + </xsl:copy> + </xsl:template> + + <xsl:template match="dep:is | dep:isNot" mode="TruthValueTestRemover"> + <xsl:choose> + <xsl:when test="@truthValue = 'UNKNOWN'"> + <dep:nullPredicate type="NULL"> + <xsl:if test="self::dep:isNot"> + <xsl:attribute name="type"> + <xsl:value-of select="'NOT NULL'"/> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="TruthValueTestRemover"/> + </dep:nullPredicate> + </xsl:when> + <xsl:otherwise> + <dep:parenthesizedValueExpression> + <dep:and> + <dep:nullPredicate type="NOT NULL"> + <xsl:apply-templates mode="TruthValueTestRemover"/> + </dep:nullPredicate> + <dep:comparisonPredicate operator="equals"> + <xsl:if test="self::dep:isNot"> + <xsl:attribute name="operator"> + <xsl:value-of select="'notEquals'"/> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="TruthValueTestRemover"/> + <ddt:booleanLiteral value="{@truthValue}"/> + </dep:comparisonPredicate> + </dep:and> + </dep:parenthesizedValueExpression> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + +</xsl:stylesheet> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:28:07
|
Revision: 1133 http://orm.svn.sourceforge.net/orm/?rev=1133&view=rev Author: mcurland Date: 2007-09-20 13:28:09 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Fixed misc build errors from [1131]. refs #223 Modified Paths: -------------- trunk/TestSuites/TestSample/TestSample.csproj Added Paths: ----------- trunk/TestSuites/AutomationTestSample/Properties/ trunk/TestSuites/AutomationTestSample/Properties/AssemblyInfo.cs Added: trunk/TestSuites/AutomationTestSample/Properties/AssemblyInfo.cs =================================================================== --- trunk/TestSuites/AutomationTestSample/Properties/AssemblyInfo.cs (rev 0) +++ trunk/TestSuites/AutomationTestSample/Properties/AssemblyInfo.cs 2007-09-20 20:28:09 UTC (rev 1133) @@ -0,0 +1,29 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: ComVisible(false)] +[assembly: NeutralResourcesLanguage("en-US")] +[assembly: AssemblyTitle("AutomationTestSample.dll")] +[assembly: AssemblyProduct("Neumont ORM Architect for Visual Studio")] +[assembly: AssemblyDescription("Neumont ORM Architect for Visual Studio - Automation Testing Sample")] +[assembly: AssemblyCompany("Neumont University")] +[assembly: AssemblyCopyright("Copyright \xA9 Neumont University. All rights reserved.")] +#if DEBUG +[assembly: AssemblyConfiguration("Debug")] +#else +[assembly: AssemblyConfiguration("Release")] +#endif + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +//[assembly: AssemblyVersion("1.0.*")] Modified: trunk/TestSuites/TestSample/TestSample.csproj =================================================================== --- trunk/TestSuites/TestSample/TestSample.csproj 2007-09-20 20:25:16 UTC (rev 1132) +++ trunk/TestSuites/TestSample/TestSample.csproj 2007-09-20 20:28:09 UTC (rev 1133) @@ -42,7 +42,7 @@ <SpecificVersion>False</SpecificVersion> <HintPath>$(ProgramFiles)\Neumont\ORM Architect for Visual Studio\bin\Neumont.Tools.ORM.SDK.TestEngine.dll</HintPath> </Reference> - <Reference Include="nunit.framework, Version=2.2.7.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL"> + <Reference Include="nunit.framework, Version=2.2.9.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> </Reference> <Reference Include="System" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 20:25:12
|
Revision: 1132 http://orm.svn.sourceforge.net/orm/?rev=1132&view=rev Author: mcurland Date: 2007-09-20 13:25:16 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Serialize standalone relationship elements with orders based on each source role player, not the entire set of links of a given type, which can leave ordered links in the wrong order on save and reload. refs #329 Modified Paths: -------------- trunk/ORMModel/Framework/Shell/SerializationEngine.cs Modified: trunk/ORMModel/Framework/Shell/SerializationEngine.cs =================================================================== --- trunk/ORMModel/Framework/Shell/SerializationEngine.cs 2007-09-20 20:22:18 UTC (rev 1131) +++ trunk/ORMModel/Framework/Shell/SerializationEngine.cs 2007-09-20 20:25:16 UTC (rev 1132) @@ -2504,6 +2504,7 @@ CustomSerializedRootRelationshipContainer[] rootContainers = ns.GetRootRelationshipContainers(); if (rootContainers != null) { + Dictionary<ModelElement, ModelElement> linksBySource = null; for (int i = 0; i < rootContainers.Length; ++i) { CustomSerializedRootRelationshipContainer container = rootContainers[i]; @@ -2514,32 +2515,81 @@ { CustomSerializedStandaloneRelationship relationship = relationships[j]; DomainRelationshipInfo relationshipInfo = dataDir.GetDomainClass(relationship.DomainClassId) as DomainRelationshipInfo; - ReadOnlyCollection<ModelElement> relationshipElements = elementDir.FindElements(relationshipInfo); - int elementCount = relationshipElements.Count; - for (int k = 0; k < elementCount; ++k) + ReadOnlyCollection<ModelElement> allRelationshipElements = elementDir.FindElements(relationshipInfo); + + // This collection is very randomly order. To maintain order within the relationship, find + // all of the unique source elements and requery to get the ordered targets for that element. + // UNDONE: Do we want to specify if we should key off the source, target, or not at all in + // the serialization specs? + int allElementCount = allRelationshipElements.Count; + if (allElementCount == 0) { - ElementLink link = relationshipElements[k] as ElementLink; - CustomSerializedStandaloneRelationshipRole[] roles = relationship.GetRoles(); - if (relationship.IsPrimaryLinkElement) + continue; + } + if (linksBySource == null) + { + linksBySource = new Dictionary<ModelElement, ModelElement>(); + } + else + { + linksBySource.Clear(); + } + for (int k = 0; k < allElementCount; ++k) + { + ModelElement sourceElement = DomainRoleInfo.GetSourceRolePlayer((ElementLink)allRelationshipElements[k]); + if (!linksBySource.ContainsKey(sourceElement)) { - SerializeElement(file, link, new SerializeExtraAttributesCallback(delegate(XmlWriter xmlFile) - { - for (int l = 0; l < roles.Length; ++l) - { - CustomSerializedStandaloneRelationshipRole role = roles[l]; - xmlFile.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); - } - })); + linksBySource[sourceElement] = sourceElement; } - else + } + IList<DomainRoleInfo> roleInfos = relationshipInfo.DomainRoles; + DomainRoleInfo sourceRoleInfo = roleInfos[0]; + if (!sourceRoleInfo.IsSource) + { + sourceRoleInfo = roleInfos[1]; + Debug.Assert(sourceRoleInfo.IsSource); + } + CustomSerializedStandaloneRelationshipRole[] customRelationshipRoles = relationship.GetRoles(); + + // The values collection is officially randomly ordered and may change over time. + // Sort the elements by Id to get a stable XML file + ICollection<ModelElement> sourceValues = linksBySource.Values; + int sourceCount = sourceValues.Count; + if (sourceCount > 1) + { + ModelElement[] sortedSources = new ModelElement[sourceCount]; + sourceValues.CopyTo(sortedSources, 0); + Array.Sort<ModelElement>(sortedSources, ModelElementGuidComparer.Instance); + sourceValues = sortedSources; + } + foreach (ModelElement element in sourceValues) + { + ReadOnlyCollection<ElementLink> relationshipElements = sourceRoleInfo.GetElementLinks(element); + int linkCount = relationshipElements.Count; + for (int k = 0; k < linkCount; ++k) { - file.WriteStartElement(relationship.ElementPrefix, relationship.ElementName, relationship.ElementNamespace); - for (int l = 0; l < roles.Length; ++l) + ElementLink link = relationshipElements[k] as ElementLink; + if (relationship.IsPrimaryLinkElement) { - CustomSerializedStandaloneRelationshipRole role = roles[l]; - file.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); + SerializeElement(file, link, new SerializeExtraAttributesCallback(delegate(XmlWriter xmlFile) + { + for (int l = 0; l < customRelationshipRoles.Length; ++l) + { + CustomSerializedStandaloneRelationshipRole role = customRelationshipRoles[l]; + xmlFile.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); + } + })); } - file.WriteEndElement(); + else + { + file.WriteStartElement(relationship.ElementPrefix, relationship.ElementName, relationship.ElementNamespace); + for (int l = 0; l < customRelationshipRoles.Length; ++l) + { + CustomSerializedStandaloneRelationshipRole role = customRelationshipRoles[l]; + file.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); + } + file.WriteEndElement(); + } } } } @@ -2553,6 +2603,25 @@ return; } + #region ModelElementGuidComparer class + /// <summary> + /// Helper class used to impose a reproducible order on a randomly + /// ordered set of model elements + /// </summary> + private class ModelElementGuidComparer : IComparer<ModelElement> + { + public static readonly IComparer<ModelElement> Instance = new ModelElementGuidComparer(); + private ModelElementGuidComparer() + { + } + #region IComparer<ModelElement> Implementation + public int Compare(ModelElement x, ModelElement y) + { + return x.Id.CompareTo(y.Id); ; + } + #endregion // IComparer<ModelElement> Implementation + } + #endregion // ModelElementGuidComparer class } #endregion // Serialization Routines #region Deserialization Routines This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-20 19:35:20
|
Revision: 1129 http://orm.svn.sourceforge.net/orm/?rev=1129&view=rev Author: mcurland Date: 2007-09-20 12:35:22 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Updated the name generation design specification to include the addition of the choices related to object type and value type names. refs #338 Modified Paths: -------------- trunk/Documentation/NameGeneration/NameGenerationSpec v1_0.doc Modified: trunk/Documentation/NameGeneration/NameGenerationSpec v1_0.doc =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-12 00:21:42
|
Revision: 1127 http://orm.svn.sourceforge.net/orm/?rev=1127&view=rev Author: mcurland Date: 2007-09-11 17:21:45 -0700 (Tue, 11 Sep 2007) Log Message: ----------- We didn't end up doing a 2007-08 drop, switch to 2007-09. refs #193 Also changed Model Browser header to 'Relational Schema' from 'Relational Schemas' Modified Paths: -------------- trunk/RelationalModel/DcilModel/Catalog.resx trunk/VersionGenerator.exe.config Modified: trunk/RelationalModel/DcilModel/Catalog.resx =================================================================== --- trunk/RelationalModel/DcilModel/Catalog.resx 2007-09-12 00:17:14 UTC (rev 1126) +++ trunk/RelationalModel/DcilModel/Catalog.resx 2007-09-12 00:21:45 UTC (rev 1127) @@ -200,7 +200,7 @@ <value>Tables</value> </data> <data name="SurveySchemaType.Schema" xml:space="preserve"> - <value>Relational Schemas</value> + <value>Relational Schema</value> </data> <data name="SurveyTableChildType.Column" xml:space="preserve"> <value>Columns</value> Modified: trunk/VersionGenerator.exe.config =================================================================== --- trunk/VersionGenerator.exe.config 2007-09-12 00:17:14 UTC (rev 1126) +++ trunk/VersionGenerator.exe.config 2007-09-12 00:21:45 UTC (rev 1127) @@ -2,7 +2,7 @@ <configuration> <appSettings> <add key="RevisionStartYearMonth" value="2006-01"/> - <add key="ReleaseYearMonth" value="2007-08"/> + <add key="ReleaseYearMonth" value="2007-09"/> <!-- ReleaseType: "CTP" or "RTM" --> <add key="ReleaseType" value="CTP"/> <!-- Changes to the major and/or minor version numbers have extreme effects across every part of the product. --> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
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. |
From: <mcu...@us...> - 2007-09-10 23:46:56
|
Revision: 1124 http://orm.svn.sourceforge.net/orm/?rev=1124&view=rev Author: mcurland Date: 2007-09-10 16:46:57 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Added ability to allow generators to require extensions from the ORM designer. The UI is a little clunky (you need to open the ORM designer to add extensions), but the large amount of additional work to do this without opening the designer file coupled with the small usability gain makes the designer-free extension enabling a low priority feature. refs #339 Modified Paths: -------------- trunk/ORMModel/Shell/ExtensionManager.cs trunk/ORMModel/Shell/ORMDocData.cs trunk/Tools/ORMCustomTool/Extender.cs trunk/Tools/ORMCustomTool/IORMGenerator.cs trunk/Tools/ORMCustomTool/ORMCustomTool.cs trunk/Tools/ORMCustomTool/ORMCustomTool.csproj trunk/Tools/ORMCustomTool/UI/MainBranch.cs trunk/Tools/ORMCustomTool/UI/ORMGeneratorSelectionControl.cs trunk/Tools/ORMCustomTool/XslORMGenerator.cs Added Paths: ----------- trunk/Tools/ORMCustomTool/ORMExtensionManager.cs Modified: trunk/ORMModel/Shell/ExtensionManager.cs =================================================================== --- trunk/ORMModel/Shell/ExtensionManager.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/ORMModel/Shell/ExtensionManager.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -77,47 +77,8 @@ checkedTypes.Add((ORMExtensionType)listViewItem.Tag); } - IList<ORMExtensionType> allExtensionTypes = extensionManager._allExtensionTypes; + AddRequiredExtensions(checkedTypes, extensionManager._allExtensionTypes); - List<Guid> loadedDomainModelIds = new List<Guid>(4 + checkedTypes.Count); - loadedDomainModelIds.Add(CoreDomainModel.DomainModelId); - loadedDomainModelIds.Add(Microsoft.VisualStudio.Modeling.Diagrams.CoreDesignSurfaceDomainModel.DomainModelId); - loadedDomainModelIds.Add(ObjectModel.ORMCoreDomainModel.DomainModelId); - loadedDomainModelIds.Add(ShapeModel.ORMShapeDomainModel.DomainModelId); - foreach (ORMExtensionType extensionType in checkedTypes) - { - loadedDomainModelIds.Add(extensionType.Type.GUID); - } - - for (int i = 0; i < checkedTypes.Count; i++) - { - foreach (ExtendsDomainModelAttribute extendsDomainModelAttribute in checkedTypes[i].Type.GetCustomAttributes(typeof(ExtendsDomainModelAttribute), false)) - { - Guid extendedModelId = extendsDomainModelAttribute.ExtendedModelId; - if (!loadedDomainModelIds.Contains(extendedModelId)) - { - // Find the missing domain model - foreach (ORMExtensionType candidateExtensionType in allExtensionTypes) - { - object[] domainObjectIdAttributes = candidateExtensionType.Type.GetCustomAttributes(typeof(DomainObjectIdAttribute), false); - if (domainObjectIdAttributes.Length <= 0) - { - continue; - } - Guid candidateModelId = ((DomainObjectIdAttribute)domainObjectIdAttributes[0]).Id; - if (extendedModelId.Equals(candidateModelId)) - { - loadedDomainModelIds.Add(candidateModelId); - checkedTypes.Add(candidateExtensionType); - break; - } - } - // If we didn't find the requested domain model, we don't need to worry about doing anything here, - // since the Store will throw later when they try to load the requesting domain model. - } - } - } - Stream stream = null; try { @@ -140,6 +101,50 @@ } } /// <summary> + /// Given a current list of extensions and all available extensions, add additional required extensions to the list + /// </summary> + public static void AddRequiredExtensions(IList<ORMExtensionType> extensions, IList<ORMExtensionType> allExtensions) + { + Dictionary<Guid, object> loadedDomainModelIds = new Dictionary<Guid, object>(4 + allExtensions.Count); + loadedDomainModelIds.Add(CoreDomainModel.DomainModelId, null); + loadedDomainModelIds.Add(Microsoft.VisualStudio.Modeling.Diagrams.CoreDesignSurfaceDomainModel.DomainModelId, null); + loadedDomainModelIds.Add(ObjectModel.ORMCoreDomainModel.DomainModelId, null); + loadedDomainModelIds.Add(ShapeModel.ORMShapeDomainModel.DomainModelId, null); + foreach (ORMExtensionType extensionType in extensions) + { + loadedDomainModelIds.Add(extensionType.Type.GUID, null); + } + + for (int i = 0; i < extensions.Count; i++) // The count check here is correct, we're growing the list as we go + { + foreach (ExtendsDomainModelAttribute extendsDomainModelAttribute in extensions[i].Type.GetCustomAttributes(typeof(ExtendsDomainModelAttribute), false)) + { + Guid extendedModelId = extendsDomainModelAttribute.ExtendedModelId; + if (!loadedDomainModelIds.ContainsKey(extendedModelId)) + { + // Find the missing domain model + foreach (ORMExtensionType candidateExtensionType in allExtensions) + { + object[] domainObjectIdAttributes = candidateExtensionType.Type.GetCustomAttributes(typeof(DomainObjectIdAttribute), false); + if (domainObjectIdAttributes.Length <= 0) + { + continue; + } + Guid candidateModelId = ((DomainObjectIdAttribute)domainObjectIdAttributes[0]).Id; + if (extendedModelId.Equals(candidateModelId)) + { + loadedDomainModelIds.Add(candidateModelId, null); + extensions.Add(candidateExtensionType); + break; + } + } + // If we didn't find the requested domain model, we don't need to worry about doing anything here, + // since the Store will throw later when they try to load the requesting domain model. + } + } + } + } + /// <summary> /// This is a custom callback class for the XSLT file that is /// responsible for adding or removing the custom extension namespaces to the ORM document. /// </summary> @@ -225,7 +230,7 @@ /// <param name="stream">The file stream that contains the ORM file.</param> /// <param name="extensionTypes">A list of extension types.</param> /// <returns>The cleaned stream.</returns> - private static Stream CleanupStream(Stream stream, IList<ORMExtensionType> extensionTypes) + public static Stream CleanupStream(Stream stream, IList<ORMExtensionType> extensionTypes) { MemoryStream outputStream = new MemoryStream((int)stream.Length); XsltArgumentList argList = new XsltArgumentList(); Modified: trunk/ORMModel/Shell/ORMDocData.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocData.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/ORMModel/Shell/ORMDocData.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -35,6 +35,7 @@ using System.Xml.Schema; using System.Collections.ObjectModel; using Neumont.Tools.Modeling.Shell.DynamicSurveyTreeGrid; +using System.Runtime.InteropServices; namespace Neumont.Tools.ORM.Shell { @@ -690,6 +691,120 @@ #endregion // Tab Restoration Hack #region Automation support /// <summary> + /// Class used for the document extensibility layer. Request + /// the "ORMExtensionManager" extension object. + /// </summary> + [ComVisible(true)] + [ClassInterface(ClassInterfaceType.AutoDispatch)] + public class ORMExtensionManagerAutomationObject + { + private ORMDesignerDocData myDocData; + /// <summary> + /// Create a new <see cref="ORMExtensionManagerAutomationObject"/> for the specific <paramref name="docData"/> + /// </summary> + /// <param name="docData">An <see cref="ORMDesignerDocData"/> instance</param> + public ORMExtensionManagerAutomationObject(ORMDesignerDocData docData) + { + myDocData = docData; + } + /// <summary> + /// Retrieve a string array of loaded extension names + /// </summary> + public string[] GetLoadedExtensions() + { + IList<ORMExtensionType> availableExtensions = ORMDesignerPackage.GetAvailableCustomExtensions(); + List<string> extensionNames = new List<string>(); + foreach (DomainModel domainModel in myDocData.Store.DomainModels) + { + Type domainModelType = domainModel.GetType(); + foreach (ORMExtensionType extensionInfo in availableExtensions) + { + if (extensionInfo.Type == domainModelType) + { + extensionNames.Add(extensionInfo.NamespaceUri); + break; + } + } + } + return extensionNames.ToArray(); + } + /// <summary> + /// Verify that the requested extensions are loaded in the current designer instance + /// </summary> + public void EnsureExtensions(string[] extensions) + { + int ensureCount; + if (extensions != null && (ensureCount = extensions.Length) != 0) + { + string[] clonedExtensions = (string[])extensions.Clone(); + IList<ORMExtensionType> availableExtensions = ORMDesignerPackage.GetAvailableCustomExtensions(); + List<ORMExtensionType> loadedExtensions = null; + foreach (DomainModel domainModel in myDocData.Store.DomainModels) + { + Type domainModelType = domainModel.GetType(); + foreach (ORMExtensionType extensionInfo in availableExtensions) + { + if (extensionInfo.Type == domainModelType) + { + string namespaceUri = extensionInfo.NamespaceUri; + for (int i = 0; i < clonedExtensions.Length; ++i) + { + if (clonedExtensions[i] == namespaceUri) + { + --ensureCount; + if (ensureCount == 0) + { + return; // Nothing to do, everything we need is already loaded + } + if (loadedExtensions == null) + { + loadedExtensions = new List<ORMExtensionType>(); + } + loadedExtensions.Add(extensionInfo); + clonedExtensions[i] = null; + } + } + break; + } + } + } + for (int i = 0; i < clonedExtensions.Length; ++i) + { + string newExtension = clonedExtensions[i]; + if (newExtension != null) + { + --ensureCount; + foreach (ORMExtensionType extensionInfo in availableExtensions) + { + if (extensionInfo.NamespaceUri == newExtension) + { + if (loadedExtensions == null) + { + loadedExtensions = new List<ORMExtensionType>(); + } + loadedExtensions.Add(extensionInfo); + break; + } + } + if (ensureCount == 0) + { + break; + } + } + } + Object streamObj; + (myDocData as EnvDTE.IExtensibleObject).GetAutomationObject("ORMXmlStream", null, out streamObj); + Stream stream = streamObj as Stream; + + Debug.Assert(stream != null); + + ExtensionManager.AddRequiredExtensions(loadedExtensions, availableExtensions); + stream = ExtensionManager.CleanupStream(stream, loadedExtensions); + myDocData.ReloadFromStream(stream); + } + } + } + /// <summary> /// Implements IExtensibleObject.GetAutomationObject. Returns the ORM XML stream for /// the "ORMXmlStream" object name and the this object for everything else. /// </summary> @@ -703,6 +818,14 @@ result = stream; return; } + else if ("ORMExtensionManager" == name) + { + // This returns an object with two methods: + // GetLoadedExtensions returns an array of current loaded extension objects + // EnsureExtensions accepts an array of extensions that need to be loaded + result = new ORMExtensionManagerAutomationObject(this); + return; + } result = this; } void IExtensibleObject.GetAutomationObject(string Name, IExtensibleObjectSite pParent, out object ppDisp) Modified: trunk/Tools/ORMCustomTool/Extender.cs =================================================================== --- trunk/Tools/ORMCustomTool/Extender.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/Tools/ORMCustomTool/Extender.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -17,6 +17,7 @@ using System.Runtime.InteropServices; using System.ComponentModel; using System.Drawing.Design; +using System.Diagnostics; namespace Neumont.Tools.ORM.ORMCustomTool { @@ -78,6 +79,15 @@ /// </summary> ~Extender() { + NotifyDeleteCookie(); + } + /// <summary> + /// Helper method to prevent the debugger from breaking when a common + /// exception is thrown deleting the cookie. + /// </summary> + [DebuggerStepThrough] + private void NotifyDeleteCookie() + { // Wrap this call in a try-catch to avoid any failure code the // Site may return. For instance, since this object is GC'ed, // the Site may have already let go of its Cookie. @@ -88,7 +98,7 @@ mySite.NotifyDelete(myCookie); } } - catch + catch { } } Modified: trunk/Tools/ORMCustomTool/IORMGenerator.cs =================================================================== --- trunk/Tools/ORMCustomTool/IORMGenerator.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/Tools/ORMCustomTool/IORMGenerator.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -93,6 +93,14 @@ } /// <summary> + /// Get required extensions for an associated input format. The extensions ensure that the input formats + /// meet additional content requirements not expressible based solely on file format. + /// </summary> + /// <param name="inputFormat">The official name of the required input format, retrieved from <see cref="RequiresInputFormats"/>.</param> + /// <returns>An enumerable of required extensions. The extensions must be enabled by the generator chosen to produce the given input format.</returns> + IEnumerable<string> GetRequiredExtensionsForInputFormat(string inputFormat); + + /// <summary> /// Returns the default name of the file generated for a specific source file name. /// </summary> /// <param name="sourceFileName">A <see cref="String"/> containing the name (without file extension) of the source ORM file.</param> Modified: trunk/Tools/ORMCustomTool/ORMCustomTool.cs =================================================================== --- trunk/Tools/ORMCustomTool/ORMCustomTool.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/Tools/ORMCustomTool/ORMCustomTool.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -517,9 +517,15 @@ ormStream = new MemoryStream(Encoding.UTF8.GetBytes(bstrInputFileContents), false); } + // Switch the ormStream to a readonly stream so we can reuse it multiple times + ormStream = new ReadOnlyStream(ormStream); + // Add the input ORM file Stream... - outputFormatStreams.Add(ORMOutputFormat.ORM, new ReadOnlyStream(ormStream)); + outputFormatStreams.Add(ORMOutputFormat.ORM, ormStream); + ORMExtensionManager ormExtensionManager = new ORMExtensionManager(projectItemDocument, ormStream); + string[] ormExtensions = null; // Delay populated if a requires is made + // Null out bstrInputFileContents to prevent its usage beyond this point. bstrInputFileContents = null; @@ -572,8 +578,30 @@ Stream readonlyOutputStream = null; try { - ormGenerator.GenerateOutput(buildItem, outputStream, readonlyOutputFormatStreams, wszDefaultNamespace); - readonlyOutputStream = new ReadOnlyStream(outputStream); + // UNDONE: Extension checking should happen in the current generator + // going back to the generator that produced the input file. We're only + // extending ORM files right now, and the ORM file doesn't have a generator, + // so we just do it here. + bool extensionsSatisfied = true; + foreach (string extension in ormGenerator.GetRequiredExtensionsForInputFormat("ORM")) + { + if (null == ormExtensions) + { + ormExtensions = ormExtensionManager.GetLoadedExtensions(); + } + if (Array.BinarySearch<string>(ormExtensions, extension) < 0) + { + extensionsSatisfied = false; + // UNDONE: Localize error messages. + message = string.Format(CultureInfo.InvariantCulture, "The extension '{0}' in the '{1}' is required for generation of the '{2}' file. The existing contents of '{3}' will not be modified. Open the 'ORM Generator Selection' dialog and choose 'Save Changes' to automatically add required extensions.", extension, "ORM", ormGenerator.OfficialName, buildItem.FinalItemSpec); + report(message, ReportType.Error, null); + } + } + if (extensionsSatisfied) + { + ormGenerator.GenerateOutput(buildItem, outputStream, readonlyOutputFormatStreams, wszDefaultNamespace); + readonlyOutputStream = new ReadOnlyStream(outputStream); + } } catch (Exception ex) { Modified: trunk/Tools/ORMCustomTool/ORMCustomTool.csproj =================================================================== --- trunk/Tools/ORMCustomTool/ORMCustomTool.csproj 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/Tools/ORMCustomTool/ORMCustomTool.csproj 2007-09-10 23:46:57 UTC (rev 1124) @@ -74,6 +74,7 @@ <Reference Include="VSLangProj80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </ItemGroup> <ItemGroup> + <Compile Include="ORMExtensionManager.cs" /> <Compile Include="Extender.cs" /> <Compile Include="ExtenderProvider.cs" /> <Compile Include="UI\BranchBase.cs"> Added: trunk/Tools/ORMCustomTool/ORMExtensionManager.cs =================================================================== --- trunk/Tools/ORMCustomTool/ORMExtensionManager.cs (rev 0) +++ trunk/Tools/ORMCustomTool/ORMExtensionManager.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -0,0 +1,237 @@ +#region Common Public License Copyright Notice +/**************************************************************************\ +* Neumont Object-Role Modeling Architect for Visual Studio * +* * +* Copyright \xA9 Neumont University. All rights reserved. * +* * +* The use and distribution terms for this software are covered by the * +* Common Public License 1.0 (http://opensource.org/licenses/cpl) which * +* can be found in the file CPL.txt at the root of this distribution. * +* By using this software in any fashion, you are agreeing to be bound by * +* the terms of this license. * +* * +* You must not remove this notice, or any other, from this software. * +\**************************************************************************/ +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using System.Reflection; +using System.Xml; +using System.Windows.Forms; + +namespace Neumont.Tools.ORM.ORMCustomTool +{ + /// <summary> + /// Extensions are additional named requirements for a given document format. + /// The extensions are treated as required content within a document format. + /// UNDONE: In the longer run, individual generators will be asked to ensure that + /// a given set of extensions are present in a returned document. For now, we + /// are not treating the document retrieved from the ORM designer as a true generator, + /// so we're just hacking this in. + /// </summary> + internal class ORMExtensionManager + { + private string[] myLoadedExtensions; + private EnvDTE.Document myDocument; + private EnvDTE.ProjectItem myProjectItem; + private Stream myStream; + public ORMExtensionManager(EnvDTE.Document document, Stream stream) + { + myDocument = document; + myStream = stream; + } + public ORMExtensionManager(EnvDTE.ProjectItem projectItem) + { + myProjectItem = projectItem; + } + /// <summary> + /// Return a sorted array of loaded extensions + /// </summary> + public string[] GetLoadedExtensions() + { + string[] retVal = myLoadedExtensions; + if (retVal == null) + { + if (myDocument == null && myProjectItem != null) + { + myDocument = myProjectItem.Document; + } + + object documentExtensionManager; + MethodInfo methodInfo; + if (null != myDocument && + null != (documentExtensionManager = myDocument.Object("ORMExtensionManager")) && + null != (methodInfo = documentExtensionManager.GetType().GetMethod("GetLoadedExtensions", Type.EmptyTypes))) + { + retVal = methodInfo.Invoke(documentExtensionManager, null) as string[]; + myDocument = null; // No longer needed + } + Stream stream = null; + if (null == retVal) + { + // First used the passed in stream + stream = myStream; + + // Next use an open text document. Note that this will already have provided + // an extension manager if this is an open ORM designer + if (stream == null && myDocument != null) + { + EnvDTE.TextDocument textDoc = myDocument.Object("TextDocument") as EnvDTE.TextDocument; + if (textDoc != null) + { + // Note that the stream will be closed with the default reader settings of the XmlReader below + stream = new MemoryStream(Encoding.UTF8.GetBytes(textDoc.StartPoint.CreateEditPoint().GetText(textDoc.EndPoint)), false); + } + } + + // Try the file directly from the project item + if (stream == null && myProjectItem != null) + { + // Note that the stream will be closed with the default reader settings of the XmlReader below + stream = new FileStream(myProjectItem.get_FileNames(0), FileMode.Open); + } + } + if (stream != null) + { + myStream = null; // No longer needed + // Attempt to open the stream as an Xml file to + // get the required extensions from the Xml + string[] namespaces = null; + int namespaceCount = 0; + try + { + XmlReaderSettings readerSettings = new XmlReaderSettings(); + readerSettings.CloseInput = true; + using (XmlReader reader = XmlReader.Create(stream, readerSettings)) + { + reader.MoveToContent(); + if (reader.NodeType == XmlNodeType.Element) + { + int attributeCount = reader.AttributeCount; + if (attributeCount != 0) + { + namespaces = new string[attributeCount]; + if (reader.MoveToFirstAttribute()) + { + do + { + if (reader.Prefix == "xmlns" || reader.Name == "xmlns") + { + // Note that some of these are standard, not extensions, but it + // isn't worth the trouble to add extra ORM knowledge here to figure it out + string value = reader.Value; + if (!string.IsNullOrEmpty(value)) + { + namespaces[namespaceCount] = reader.Value; + ++namespaceCount; + } + } + } while (reader.MoveToNextAttribute()); + } + } + } + } + } + catch (XmlException) + { + // Nothing to do + } + if (namespaceCount != 0) + { + if (namespaceCount != namespaces.Length) + { + Array.Resize(ref namespaces, namespaceCount); + } + retVal = namespaces; + } + } + if (retVal == null) + { + retVal = new string[0]; + } + else + { + Array.Sort<string>(retVal); + } + myLoadedExtensions = retVal; + } + return retVal; + } + /// <summary> + /// Ensure that the current project item has the required extensions loaded. + /// This is only called after verifying that the current project item does + /// not satisfy the requirements. + /// </summary> + /// <param name="projectItem">The <see cref="EnvDTE.ProjectItem"/> to modify</param> + /// <param name="extensions">An <see cref="T:ICollection{System.String}"/> of additional required extensions</param> + public static bool EnsureExtensions(EnvDTE.ProjectItem projectItem, ICollection<string> extensions) + { + ServiceProvider provider = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)projectItem.DTE); + // UNDONE: Localize message strings in here + if ((int)DialogResult.No == VsShellUtilities.ShowMessageBox( + provider, + "Additional extensions are required to support the chosen generators. Would you like to load the required extensions now?", + "ORM Generator Selection", + OLEMSGICON.OLEMSGICON_QUERY, + OLEMSGBUTTON.OLEMSGBUTTON_YESNO, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST)) + { + return false; + } + EnvDTE.Document document = projectItem.Document; + bool secondPass = false; + bool tryDocument = true; + while (tryDocument) + { + object documentExtensionManager; + MethodInfo methodInfo; + if (null != document && + null != (documentExtensionManager = document.Object("ORMExtensionManager")) && + null != (methodInfo = documentExtensionManager.GetType().GetMethod("EnsureExtensions", new Type[] { typeof(string[]) }))) + { + string[] extensionsArray = new string[extensions.Count]; + extensions.CopyTo(extensionsArray, 0); + methodInfo.Invoke(documentExtensionManager, new object[] { extensionsArray }); + return true; + } + + if (secondPass) + { + return false; + } + tryDocument = false; + secondPass = true; + + // UNDONE: Localize message strings in here + if ((int)DialogResult.No == VsShellUtilities.ShowMessageBox( + provider, + "The .ORM file must be open in the default designer to add extensions. Would you like to open or reopen the document now?", + "ORM Generator Selection", + OLEMSGICON.OLEMSGICON_QUERY, + OLEMSGBUTTON.OLEMSGBUTTON_YESNO, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST)) + { + return false; + } + + if (document != null) + { + document.Close(EnvDTE.vsSaveChanges.vsSaveChangesPrompt); + document = projectItem.Document; + } + if (document == null) + { + projectItem.Open(Guid.Empty.ToString("B")).Visible = true; + document = projectItem.Document; + tryDocument = true; + } + } + return false; + } + } +} Modified: trunk/Tools/ORMCustomTool/UI/MainBranch.cs =================================================================== --- trunk/Tools/ORMCustomTool/UI/MainBranch.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/Tools/ORMCustomTool/UI/MainBranch.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -69,6 +69,21 @@ } } + public IEnumerable<IORMGenerator> SelectedGenerators + { + get + { + foreach (OutputFormatBranch branch in _branches.Values) + { + IORMGenerator selectedGenerator = branch.SelectedORMGenerator; + if (selectedGenerator != null) + { + yield return selectedGenerator; + } + } + } + } + public bool IsPrimaryDisplayItem(int index) { OutputFormatBranch branch = _branches.Values[index]; Modified: trunk/Tools/ORMCustomTool/UI/ORMGeneratorSelectionControl.cs =================================================================== --- trunk/Tools/ORMCustomTool/UI/ORMGeneratorSelectionControl.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/Tools/ORMCustomTool/UI/ORMGeneratorSelectionControl.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -206,6 +206,42 @@ { if (_savedChanges) { + // Make sure the current document has the necessary + // extensions loaded. + // UNDONE: We should be able to do this with the document + // closed or open as text as well via a registered service + // on the ORMDesignerPackage, but this is sufficient for now. + Dictionary<string, string> requiredExtensions = null; + string[] loadedExtensions = null; + foreach (IORMGenerator selectedGenerator in _mainBranch.SelectedGenerators) + { + foreach (string requiredExtension in selectedGenerator.GetRequiredExtensionsForInputFormat("ORM")) + { + if (loadedExtensions == null) + { + loadedExtensions = (new ORMExtensionManager(_projectItem)).GetLoadedExtensions(); + } + if (Array.BinarySearch<string>(loadedExtensions, requiredExtension) < 0) + { + if (requiredExtensions == null) + { + requiredExtensions = new Dictionary<string, string>(); + } + else if (requiredExtensions.ContainsKey(requiredExtension)) + { + continue; + } + requiredExtensions.Add(requiredExtension, requiredExtension); + } + } + } + if (requiredExtensions != null) + { + _savedChanges = ORMExtensionManager.EnsureExtensions(_projectItem, requiredExtensions.Values); + } + } + if (_savedChanges) + { // Delete the removed items from the project if (_removedItems != null) { Modified: trunk/Tools/ORMCustomTool/XslORMGenerator.cs =================================================================== --- trunk/Tools/ORMCustomTool/XslORMGenerator.cs 2007-09-10 23:11:55 UTC (rev 1123) +++ trunk/Tools/ORMCustomTool/XslORMGenerator.cs 2007-09-10 23:46:57 UTC (rev 1124) @@ -64,17 +64,27 @@ this._generatesSupportFile = Convert.ToBoolean((int)generatorKey.GetValue("GeneratesSupportFile", 0)); this._customTool = generatorKey.GetValue("CustomTool", null) as string; - string sourceInputFormat = this._sourceInputFormat = generatorKey.GetValue("SourceInputFormat", null) as string; + Dictionary<string, IEnumerable<string>> extensions = null; + string sourceInputFormat = generatorKey.GetValue("SourceInputFormat", null) as string; Debug.Assert(sourceInputFormat != null); - string[] referenceInputFormats = this._referenceInputFormats = generatorKey.GetValue("ReferenceInputFormats", EmptyStringArray) as string[]; + string[] referenceInputFormats = generatorKey.GetValue("ReferenceInputFormats", EmptyStringArray) as string[]; string[] prequisiteInputFormats = generatorKey.GetValue("PrequisiteInputFormats", EmptyStringArray) as string[]; List<string> requiresInputFormats; requiresInputFormats = new List<string>(referenceInputFormats.Length + prequisiteInputFormats.Length + 1); - requiresInputFormats.Add(sourceInputFormat); - requiresInputFormats.AddRange(referenceInputFormats); - requiresInputFormats.AddRange(prequisiteInputFormats); + requiresInputFormats.Add(sourceInputFormat = StripFormatExtensions(sourceInputFormat, ref extensions)); + for (int i = 0; i < referenceInputFormats.Length; ++i) + { + requiresInputFormats.Add(referenceInputFormats[i] = StripFormatExtensions(referenceInputFormats[i], ref extensions)); + } + for (int i = 0; i < prequisiteInputFormats.Length; ++i) + { + requiresInputFormats.Add(StripFormatExtensions(prequisiteInputFormats[i], ref extensions)); + } + this._sourceInputFormat = sourceInputFormat; + this._referenceInputFormats = referenceInputFormats; + this._requiredExtensions = extensions; this._requiresInputFormats = new ReadOnlyCollection<string>(requiresInputFormats); this._transform = new XslCompiledTransform(System.Diagnostics.Debugger.IsAttached); @@ -87,6 +97,46 @@ } } + private static readonly char[] _extensionSplitChars = new char[] { ' ' }; + private static string StripFormatExtensions(string format, ref Dictionary<string, IEnumerable<string>> extensions) + { + string[] substrings = format.Split(_extensionSplitChars, StringSplitOptions.RemoveEmptyEntries); + int substringCount = substrings.Length; + if (substringCount > 0) + { + format = substrings[0]; + if (substringCount > 1) + { + string[] oldExtensions = null; + if (extensions == null) + { + extensions = new Dictionary<string, IEnumerable<string>>(); + oldExtensions = null; + } + else + { + IEnumerable<string> oldEntry; + if (extensions.TryGetValue(format, out oldEntry)) + { + oldExtensions = (string[])oldEntry; + } + } + int oldLength = (oldExtensions != null) ? oldExtensions.Length : 0; + string[] newExtensions = new string[oldLength + substringCount - 1]; + if (oldLength != 0) + { + oldExtensions.CopyTo(newExtensions, 0); + } + for (int i = 1; i < substringCount; ++i, ++oldLength) + { + newExtensions[oldLength] = substrings[i]; + } + extensions[format] = newExtensions; + } + } + return format; + } + private void LoadTransform() { this._transform.Load(this._transformCanonicalUri, XsltSettings.TrustedXslt, XmlResolver); @@ -148,6 +198,16 @@ get { return this._providesOutputFormat; } } + private readonly IDictionary<string, IEnumerable<string>> _requiredExtensions; + public IEnumerable<string> GetRequiredExtensionsForInputFormat(string outputFormat) + { + IDictionary<string, IEnumerable<string>> dictionary = _requiredExtensions; + IEnumerable<string> retVal; + return (dictionary != null && dictionary.TryGetValue(outputFormat, out retVal)) ? + retVal : + EmptyStringArray; + } + private readonly bool _generatesSupportFile; public bool GeneratesSupportFile { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 23:11:51
|
Revision: 1123 http://orm.svn.sourceforge.net/orm/?rev=1123&view=rev Author: mcurland Date: 2007-09-10 16:11:55 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Fix random extension manager issue with corrupt store on reload. DomainRoleInfo is a per-store object and should never be statically cached. DomainPropertyInfo should most likely also not be cached (can't prove it, but tempting fate to avoid a hashed lookup is stupid). Attributes on domain properties are stable and may be cached. Fixed FactTypeShape property caching appropriately. refs #265 Modified Paths: -------------- trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs Modified: trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs =================================================================== --- trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs 2007-09-10 23:09:52 UTC (rev 1122) +++ trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs 2007-09-10 23:11:55 UTC (rev 1123) @@ -64,43 +64,36 @@ } private static readonly object LockObject = new object(); - private static volatile bool Initialized; - private static DomainPropertyInfo ConstraintDisplayPositionDomainPropertyInfo; + private static volatile bool myCustomPropertyAttributesInitialized; private static Attribute[] ConstraintDisplayPositionDomainPropertyAttributes; - private static DomainPropertyInfo DisplayOrientationDomainPropertyInfo; private static Attribute[] DisplayOrientationDomainPropertyAttributes; - private static DomainPropertyInfo DisplayRoleNamesDomainPropertyInfo; private static Attribute[] DisplayRoleNamesDomainPropertyAttributes; - private static DomainPropertyInfo NameDomainPropertyInfo; private static Attribute[] NameDomainPropertyAttributes; - private static DomainPropertyInfo IsIndependentDomainPropertyInfo; private static Attribute[] IsIndependentDomainPropertyAttributes; - private static DomainRoleInfo NestedFactTypeDomainRoleInfo; private static Attribute[] NestedFactTypeDomainRoleAttributes; - private static DomainRoleInfo NestingTypeDomainRoleInfo; private static Attribute[] NestingTypeDomainRoleAttributes; - private void EnsureDomainPropertiesInitialized(DomainDataDirectory domainDataDirectory) + private void EnsureDomainAttributesInitialized(DomainDataDirectory domainDataDirectory) { - if (!Initialized) + if (!myCustomPropertyAttributesInitialized) { lock (LockObject) { - if (!Initialized) + if (!myCustomPropertyAttributesInitialized) { - ConstraintDisplayPositionDomainPropertyAttributes = GetDomainPropertyAttributes(ConstraintDisplayPositionDomainPropertyInfo = domainDataDirectory.FindDomainProperty(FactTypeShape.ConstraintDisplayPositionDomainPropertyId)); - DisplayOrientationDomainPropertyAttributes = GetDomainPropertyAttributes(DisplayOrientationDomainPropertyInfo = domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayOrientationDomainPropertyId)); - DisplayRoleNamesDomainPropertyAttributes = GetDomainPropertyAttributes(DisplayRoleNamesDomainPropertyInfo = domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRoleNamesDomainPropertyId)); - NameDomainPropertyAttributes = GetDomainPropertyAttributes(NameDomainPropertyInfo = domainDataDirectory.FindDomainProperty(ORMNamedElement.NameDomainPropertyId)); - IsIndependentDomainPropertyAttributes = GetDomainPropertyAttributes(IsIndependentDomainPropertyInfo = domainDataDirectory.FindDomainProperty(ObjectType.IsIndependentDomainPropertyId)); - NestedFactTypeDomainRoleAttributes = ProcessAttributes(GetRolePlayerPropertyAttributes(NestedFactTypeDomainRoleInfo = domainDataDirectory.FindDomainRole(Objectification.NestedFactTypeDomainRoleId))); - NestingTypeDomainRoleAttributes = ProcessAttributes(GetRolePlayerPropertyAttributes(NestingTypeDomainRoleInfo = domainDataDirectory.FindDomainRole(Objectification.NestingTypeDomainRoleId))); - Initialized = true; + ConstraintDisplayPositionDomainPropertyAttributes = GetDomainPropertyAttributes(domainDataDirectory.FindDomainProperty(FactTypeShape.ConstraintDisplayPositionDomainPropertyId)); + DisplayOrientationDomainPropertyAttributes = GetDomainPropertyAttributes(domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayOrientationDomainPropertyId)); + DisplayRoleNamesDomainPropertyAttributes = GetDomainPropertyAttributes(domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRoleNamesDomainPropertyId)); + NameDomainPropertyAttributes = GetDomainPropertyAttributes(domainDataDirectory.FindDomainProperty(ORMNamedElement.NameDomainPropertyId)); + IsIndependentDomainPropertyAttributes = GetDomainPropertyAttributes(domainDataDirectory.FindDomainProperty(ObjectType.IsIndependentDomainPropertyId)); + NestedFactTypeDomainRoleAttributes = AddExpandableElementTypeConverterAttribute(GetRolePlayerPropertyAttributes(domainDataDirectory.FindDomainRole(Objectification.NestedFactTypeDomainRoleId))); + NestingTypeDomainRoleAttributes = AddExpandableElementTypeConverterAttribute(GetRolePlayerPropertyAttributes(domainDataDirectory.FindDomainRole(Objectification.NestingTypeDomainRoleId))); + myCustomPropertyAttributesInitialized = true; } } } } - private static Attribute[] ProcessAttributes(Attribute[] attributes) + private static Attribute[] AddExpandableElementTypeConverterAttribute(Attribute[] attributes) { List<Attribute> newAttributes = new List<Attribute>(attributes.Length + 1); foreach (Attribute attribute in attributes) @@ -127,16 +120,17 @@ { FactTypeShape factTypeShape = PresentationElement; ObjectType nestingType = factType.NestingType; - EnsureDomainPropertiesInitialized(factType.Store.DomainDataDirectory); + DomainDataDirectory domainDataDirectory = factType.Store.DomainDataDirectory; + EnsureDomainAttributesInitialized(domainDataDirectory); return new PropertyDescriptorCollection(new PropertyDescriptor[]{ - CreatePropertyDescriptor(factTypeShape, ConstraintDisplayPositionDomainPropertyInfo, ConstraintDisplayPositionDomainPropertyAttributes), - CreatePropertyDescriptor(factTypeShape, DisplayOrientationDomainPropertyInfo, DisplayOrientationDomainPropertyAttributes), - CreatePropertyDescriptor(factTypeShape, DisplayRoleNamesDomainPropertyInfo, DisplayRoleNamesDomainPropertyAttributes), - CreatePropertyDescriptor(nestingType, NameDomainPropertyInfo, NameDomainPropertyAttributes), - CreatePropertyDescriptor(nestingType, IsIndependentDomainPropertyInfo, IsIndependentDomainPropertyAttributes), - new ObjectificationRolePlayerPropertyDescriptor(factType, NestingTypeDomainRoleInfo, NestedFactTypeDomainRoleAttributes), - new ObjectificationRolePlayerPropertyDescriptor(nestingType, NestedFactTypeDomainRoleInfo, NestingTypeDomainRoleAttributes) + CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.ConstraintDisplayPositionDomainPropertyId), ConstraintDisplayPositionDomainPropertyAttributes), + CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayOrientationDomainPropertyId), DisplayOrientationDomainPropertyAttributes), + CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRoleNamesDomainPropertyId), DisplayRoleNamesDomainPropertyAttributes), + CreatePropertyDescriptor(nestingType, domainDataDirectory.FindDomainProperty(ORMNamedElement.NameDomainPropertyId), NameDomainPropertyAttributes), + CreatePropertyDescriptor(nestingType, domainDataDirectory.FindDomainProperty(ObjectType.IsIndependentDomainPropertyId), IsIndependentDomainPropertyAttributes), + new ObjectificationRolePlayerPropertyDescriptor(factType, domainDataDirectory.FindDomainRole(Objectification.NestingTypeDomainRoleId), NestedFactTypeDomainRoleAttributes), + new ObjectificationRolePlayerPropertyDescriptor(nestingType, domainDataDirectory.FindDomainRole(Objectification.NestedFactTypeDomainRoleId), NestingTypeDomainRoleAttributes) }); } return base.GetProperties(attributes); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 23:09:49
|
Revision: 1122 http://orm.svn.sourceforge.net/orm/?rev=1122&view=rev Author: mcurland Date: 2007-09-10 16:09:52 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Relational name generation is looping, get a less fragile algorithm. refs #338 Also changed prefix for old oial model, the serializer does not handle duplicate preferred prefixes. Modified Paths: -------------- trunk/OIALModel/OIALModel.SerializationExtensions.cs trunk/OIALModel/OIALModel.SerializationExtensions.xml trunk/RelationalModel/OialDcilBridge/NameGeneration.cs Modified: trunk/OIALModel/OIALModel.SerializationExtensions.cs =================================================================== --- trunk/OIALModel/OIALModel.SerializationExtensions.cs 2007-09-10 23:07:39 UTC (rev 1121) +++ trunk/OIALModel/OIALModel.SerializationExtensions.cs 2007-09-10 23:09:52 UTC (rev 1122) @@ -34,7 +34,7 @@ { get { - return "oial"; + return "oial0"; } } string ICustomSerializedDomainModel.DefaultElementPrefix @@ -48,7 +48,7 @@ protected static string[,] GetCustomElementNamespaces() { string[,] ret = new string[1, 3]; - ret[0, 0] = "oial"; + ret[0, 0] = "oial0"; ret[0, 1] = "http://schemas.neumont.edu/ORM/2006-01/OIALModel"; ret[0, 2] = "OIALModel.xsd"; return ret; Modified: trunk/OIALModel/OIALModel.SerializationExtensions.xml =================================================================== --- trunk/OIALModel/OIALModel.SerializationExtensions.xml 2007-09-10 23:07:39 UTC (rev 1121) +++ trunk/OIALModel/OIALModel.SerializationExtensions.xml 2007-09-10 23:09:52 UTC (rev 1122) @@ -19,7 +19,7 @@ </se:Copyright> <se:DomainModel Class="OIALDomainModel"> <se:Namespaces> - <se:Namespace Prefix="oial" URI="http://schemas.neumont.edu/ORM/2006-01/OIALModel" SchemaFile="OIALModel.xsd" DefaultPrefix="true"/> + <se:Namespace Prefix="oial0" URI="http://schemas.neumont.edu/ORM/2006-01/OIALModel" SchemaFile="OIALModel.xsd" DefaultPrefix="true"/> </se:Namespaces> <se:RootElements> <se:RootElement Class="OIALModel" Name="Model"/> Modified: trunk/RelationalModel/OialDcilBridge/NameGeneration.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-10 23:07:39 UTC (rev 1121) +++ trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-10 23:09:52 UTC (rev 1122) @@ -10,6 +10,7 @@ using System.Text.RegularExpressions; using System.Diagnostics; using System.Globalization; +using System.Collections; namespace Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge { @@ -55,107 +56,347 @@ #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>(); + UniqueNameGenerator uniqueChecker = new UniqueNameGenerator(); + LinkedElementCollection<Table> tables = schema.TableCollection; + + // Generate table names + uniqueChecker.GenerateUniqueElementNames( + tables, + delegate(object element, string longerThan) + { + return GenerateTableName((Table)element, longerThan); + }, + delegate(object element, string longerThan) + { + ((Table)element).Name = longerThan; + }); + foreach (Table table in tables) { - //table names - CallGeneratorForTableName(table, tableNames, null); - //column names - tempNames.Clear(); - LinkedElementCollection<Column> columns = table.ColumnCollection; - foreach (Column column in columns) - { - CallGeneratorForColumnName(column, tempNames, null); - } + uniqueChecker.GenerateUniqueElementNames( + table.ColumnCollection, + delegate(object element, string longerThan) + { + return GenerateColumnName((Column)element, longerThan); + }, + delegate(object element, string longerThan) + { + ((Column)element).Name = longerThan; + }); //constraint names LinkedElementCollection<ReferenceConstraint> constraints; - if (null != (constraints = table.ReferenceConstraintCollection)) + if (0 != (constraints = table.ReferenceConstraintCollection).Count) { - tempNames.Clear(); - foreach (ReferenceConstraint constraint in constraints) - { - CallGeneratorForConstraintName(constraint, tempNames, null); - } + uniqueChecker.GenerateUniqueElementNames( + constraints, + delegate(object element, string longerThan) + { + return GenerateConstraintName((Constraint)element, longerThan); + }, + delegate(object element, string longerThan) + { + ((Constraint)element).Name = longerThan; + }); } } } #endregion // GenerateAllNames method - #region private helper methods - private static void CallGeneratorForTableName(Table table, Dictionary<string, ConceptualDatabaseModelElement> tableNames, string tableName) + #region Unique name generation algorithm + /// <summary> + /// Generate a candidate name for the given <paramref name="element"/> + /// </summary> + /// <param name="element">The element to generate a candidate name for</param> + /// <param name="longerThan">A previously generated name. Generate a longer form of the name. Generate a shorter name if this is null.</param> + /// <returns>The candidate name, or <see langword="null"/> if a longer name is not available.</returns> + private delegate string GenerateCandidateElementNameCallback(object element, string longerThan); + /// <summary> + /// Set the name for the given element. Used by GenerateUniqueElementNames + /// </summary> + private delegate void SetElementNameCallback(object element, string elementName); + private struct UniqueNameGenerator { - CallGenerator(table, tableNames, tableName, - new GeneratorCall(delegate(ConceptualDatabaseModelElement element, string longerThan) + #region ElementNode class + /// <summary> + /// A linked list node class. LinkedList{} is too hard to modify during iteration, + /// and a LinkedListNode{} requires a LinkedList, so we rolled our own. + /// </summary> + private class ElementNode + { + private object myElement; + private ElementNode myNext; + private ElementNode myPrev; + public ElementNode(object element) { - 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) + myElement = element; + } + /// <summary> + /// Set the next element + /// </summary> + /// <param name="next">Next element. If next has a previous element, then the head of the next element is inserted.</param> + /// <param name="head">Reference to head node</param> + public void SetNext(ElementNode next, ref ElementNode head) { - 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) + Debug.Assert(next != null); + if (next.myPrev != null) + { + next.myPrev.SetNext(GetHead(), ref head); + return; + } + if (myNext != null) + { + myNext.myPrev = next.GetTail(); + } + if (myPrev == null) + { + head = this; + } + myNext = next; + next.myPrev = this; + } + /// <summary> + /// The element passed to the constructor + /// </summary> + public object Element { - 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) + get + { + return myElement; + } + } + /// <summary> + /// Get the next node + /// </summary> + public ElementNode Next + { + get + { + return myNext; + } + } + /// <summary> + /// Get the previous node + /// </summary> + public ElementNode Previous + { + get + { + return myPrev; + } + } + /// <summary> + /// Get the head element in the linked list + /// </summary> + public ElementNode GetHead() + { + ElementNode retVal = this; + ElementNode prev; + while (null != (prev = retVal.myPrev)) + { + retVal = prev; + } + return retVal; + } + /// <summary> + /// Get the tail element in the linked list + /// </summary> + public ElementNode GetTail() + { + ElementNode retVal = this; + ElementNode next; + while (null != (next = retVal.myNext)) + { + retVal = next; + } + return retVal; + } + /// <summary> + /// Detach the current node + /// </summary> + /// <param name="headNode"></param> + public void Detach(ref ElementNode headNode) + { + if (myPrev == null) + { + headNode = myNext; + } + else + { + myPrev.myNext = myNext; + } + if (myNext != null) + { + myNext.myPrev = myPrev; + } + myNext = null; + myPrev = null; + } + } + #endregion // ElementNode class + #region Fields + /// <summary> + /// Map already generated names into a dictionary that contains either one of the element + /// objects or a linked list of objects. Linked lists contain duplicate nodes + /// </summary> + private Dictionary<string, object> myNameMappingDictionary; + /// <summary> + /// A dictionary of unresolved names, corresponds to keys in the nameMappingDictionary + /// </summary> + Dictionary<string, string> myUnresolvedNames; + #endregion // Fields + #region Public methods + public void GenerateUniqueElementNames(IEnumerable elements, GenerateCandidateElementNameCallback generateName, SetElementNameCallback setName) { - if (null != nameConflictElement) + if (myNameMappingDictionary != null) { - //set the value in the collection to null so this element does not have yet another name generated - existingNames[curName] = null; - //generate a new name for this element as well - CallGenerator(nameConflictElement, existingNames, curName, generatorCall); + myNameMappingDictionary.Clear(); } + else + { + myNameMappingDictionary = new Dictionary<string, object>(); + } + if (myUnresolvedNames != null) + { + myUnresolvedNames.Clear(); + } + // Generate initial names + foreach (object element in elements) + { + string elementName = generateName(element, null); + if (elementName != null) + { + AddElement(element, elementName); + } + } - curName = generatorCall(element, curName); + Dictionary<string, object> nameMappingDictionary = myNameMappingDictionary; + while (myUnresolvedNames != null && 0 != myUnresolvedNames.Count) + { + // Walk the existing unresolved names and attempt to resolve them further. + // Iterate until we can't resolve any more + Dictionary<string, string> unresolvedNames = myUnresolvedNames; + myUnresolvedNames = null; - if (existingNames.ContainsKey(curName)) + foreach (string currentName in unresolvedNames.Values) + { + // If we've added this name as unresolved during this pass, then take it back out + // We'll a + if (myUnresolvedNames != null && myUnresolvedNames.ContainsKey(currentName)) + { + myUnresolvedNames.Remove(currentName); + } + ElementNode startHeadNode = (ElementNode)nameMappingDictionary[currentName]; + ElementNode headNode = startHeadNode; + ElementNode nextNode = headNode; + while (nextNode != null) + { + ElementNode currentNode = nextNode; + nextNode = currentNode.Next; + + object element = currentNode.Element; + string newName = generateName(element, currentName); + // Name generation can return null if the longerThan condition cannot be satisfied + if (newName != null && newName.Length > currentName.Length) + { + currentNode.Detach(ref headNode); + // UNDONE: Is it worth reusing the old node? + AddElement(element, newName); + } + } + + // Manage the remains of the list in the dictionary + if (headNode == null) + { + // Everything detached from this name, remove the key + nameMappingDictionary.Remove(currentName); + } + else if (headNode != startHeadNode) + { + nameMappingDictionary[currentName] = headNode; + } + } + } + + // Walk the set, appending additional numbers as needed, and set the names + foreach (KeyValuePair<string, object> pair in nameMappingDictionary) { - //mark the conflicting element to have a new name generated as well - nameConflictElement = existingNames[curName]; + object element = pair.Value; + ElementNode node = element as ElementNode; + if (node != null) + { + // We added these in reverse order, so walk backwards to number them + ElementNode tail = node.GetTail(); + if (node == tail) + { + setName(node.Element, pair.Key); + } + else + { + // We need to resolve further + string baseName = pair.Key; + int currentIndex = 0; + ElementNode nextNode = tail; + while (nextNode != null) + { + element = nextNode.Element; + nextNode = nextNode.Previous; // We started at the tail, walk backwards + + string candidateName; + do + { + ++currentIndex; + candidateName = baseName + currentIndex.ToString(); + } while (nameMappingDictionary.ContainsKey(candidateName)); + + // If we get out of the loop, then we finally have a unique name + setName(element, candidateName); + } + } + } + else + { + setName(element, pair.Key); + } } + } + #endregion // Public methods + #region Helper methods + private void AddElement(object element, string elementName) + { + object existing; + Dictionary<string, object> nameMappingDictionary = myNameMappingDictionary; + if (nameMappingDictionary.TryGetValue(elementName, out existing)) + { + // Note: We use LinkedListNode here directly instead of a LinkedList + // to facilitate dynamically adding/removing elements during iteration + ElementNode node = existing as ElementNode; + if (node == null) + { + // Record the unresolvedName + if (myUnresolvedNames == null) + { + myUnresolvedNames = new Dictionary<string, string>(); + } + myUnresolvedNames[elementName] = elementName; + + // Create a node for the original element + node = new ElementNode(existing); + } + + ElementNode newNode = new ElementNode(element); + newNode.SetNext(node, ref node); + nameMappingDictionary[elementName] = newNode; + } else { - //no conflict, so we are done - break; + nameMappingDictionary[elementName] = element; } } - existingNames.Add(curName, element); - - //set the name - Table table; - Column column; - Constraint constraint; - if (null != (constraint = element as Constraint)) - { - constraint.Name = curName; - } - else if (null != (column = element as Column)) - { - column.Name = curName; - } - else if (null != (table = element as Table)) - { - table.Name = curName; - } + #endregion // Helper methods } - #endregion // private helper methods + #endregion // Unique name generation algorithm #region UNDONE: temporary static imitation of an IDatabaseNameGenerator implementation private static Regex myReplaceFieldsPattern; private static Regex myNumberPattern; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 23:07:35
|
Revision: 1121 http://orm.svn.sourceforge.net/orm/?rev=1121&view=rev Author: mcurland Date: 2007-09-10 16:07:39 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Changed implied independence to not apply to value types. refs #327 Modified Paths: -------------- trunk/ORMModel/ObjectModel/ObjectType.cs Modified: trunk/ORMModel/ObjectModel/ObjectType.cs =================================================================== --- trunk/ORMModel/ObjectModel/ObjectType.cs 2007-09-10 23:06:05 UTC (rev 1120) +++ trunk/ORMModel/ObjectModel/ObjectType.cs 2007-09-10 23:07:39 UTC (rev 1121) @@ -1576,7 +1576,7 @@ { get { - return this.IsIndependent || (this.ImpliedMandatoryConstraint == null && this.AllowIsIndependent(false)); + return this.IsIndependent || (!this.IsValueType && this.ImpliedMandatoryConstraint == null && this.AllowIsIndependent(false)); } } /// <summary> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 23:04:38
|
Revision: 1119 http://orm.svn.sourceforge.net/orm/?rev=1119&view=rev Author: mcurland Date: 2007-09-10 16:04:41 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Modified the ColumnHasConceptTypeChild Path to allow duplicate ConceptTypeChildren, allowing us to record the full path, from the column to the ConceptType to the identifier for that ConceptType. Using the new Path restructured FindTarget to properly return the correct column. refs #328. Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/GeneratedCode/DomainRelationships.cs trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs trunk/RelationalModel/OialDcilBridge/OialDcilBridge.dsl Modified: trunk/RelationalModel/OialDcilBridge/GeneratedCode/DomainRelationships.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/GeneratedCode/DomainRelationships.cs 2007-09-10 23:03:11 UTC (rev 1118) +++ trunk/RelationalModel/OialDcilBridge/GeneratedCode/DomainRelationships.cs 2007-09-10 23:04:41 UTC (rev 1119) @@ -2463,7 +2463,7 @@ [DslDesign::DisplayNameResource("Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ColumnHasConceptTypeChild.DisplayName", typeof(global::Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel), "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.GeneratedCode.DomainModelResx")] [DslDesign::DescriptionResource("Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ColumnHasConceptTypeChild.Description", typeof(global::Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ORMAbstractionToConceptualDatabaseBridgeDomainModel), "Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.GeneratedCode.DomainModelResx")] [global::System.CLSCompliant(true)] - [DslModeling::DomainRelationship()] + [DslModeling::DomainRelationship(AllowsDuplicates = true)] [DslModeling::DomainObjectId("ccbcab63-ade4-43fa-8e29-8a598b0969f5")] public partial class ColumnHasConceptTypeChild : DslModeling::ElementLink { @@ -2650,24 +2650,6 @@ } return outLinks.AsReadOnly(); } - /// <summary> - /// Get the one ColumnHasConceptTypeChild link between a given Columnand a ConceptTypeChild. - /// </summary> - [global::System.Diagnostics.DebuggerStepThrough] - [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011")] - public static global::Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ColumnHasConceptTypeChild GetLink( global::Neumont.Tools.RelationalModels.ConceptualDatabase.Column source, global::Neumont.Tools.ORMAbstraction.ConceptTypeChild target ) - { - global::System.Collections.Generic.IList<global::Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ColumnHasConceptTypeChild> links = DslModeling::DomainRoleInfo.GetElementLinks<global::Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ColumnHasConceptTypeChild>(source, global::Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ColumnHasConceptTypeChild.ColumnDomainRoleId); - foreach ( global::Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge.ColumnHasConceptTypeChild link in links ) - { - if ( target.Equals(link.ConceptTypeChild) ) - { - return link; - } - } - return null; - } - #endregion } } Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-10 23:03:11 UTC (rev 1118) +++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-10 23:04:41 UTC (rev 1119) @@ -316,7 +316,9 @@ if (TableIsPrimarilyForConceptType.GetTable(conceptType) == null && TableIsAlsoForConceptType.GetLink(table, conceptType) == null) { TableIsAlsoForConceptType tableIsAlsoForConceptType = new TableIsAlsoForConceptType(table, conceptType); - tableIsAlsoForConceptType.AssimilationPath.AddRange(assimilationPath); + ConceptTypeAssimilatesConceptType[] assimilationPathReversed = assimilationPath.ToArray(); + Array.Reverse(assimilationPathReversed); + tableIsAlsoForConceptType.AssimilationPath.AddRange(assimilationPathReversed); } // For all Assimilations that the ConceptType is the Parent of, if the assimilation is set to absorb, // then recursively add the ConceptTypes it assimilates to the table as a TableIsAlsoForConceptType as well. @@ -505,89 +507,62 @@ /// <summary> /// Creates columns for a ConceptType for every Table that the ConceptType plays a role in, as a TableIsPrimarilyForConceptType or TableIsAlsoForConceptType relationship. /// </summary> - private static void CreateColumns(ConceptType conceptType) { - List<ConceptTypeChild> preferredConceptTypeChildList = GetPreferredConceptTypeChildrenForConceptType(conceptType); List<Column> columnsForConceptType = new List<Column>(); - - foreach (ConceptTypeChild conceptTypeChild in ConceptTypeChild.GetLinksToTargetCollection(conceptType)) + foreach (InformationType informationType in InformationType.GetLinksToInformationTypeFormatCollection(conceptType)) { - if (!(conceptTypeChild is ConceptTypeAssimilatesConceptType)) + columnsForConceptType.Add(GetColumnForInformationType(informationType, new Stack<ConceptTypeChild>())); + } + foreach (ConceptTypeRelatesToConceptType conceptTypeRelation in ConceptTypeRelatesToConceptType.GetLinksToRelatedConceptTypeCollection(conceptType)) + { + columnsForConceptType.AddRange(GetColumnsForConceptTypeRelation(conceptTypeRelation, new Stack<ConceptTypeChild>())); + } + foreach (ConceptTypeAssimilatesConceptType assimilation in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptType)) + { + switch (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation)) { - columnsForConceptType.AddRange(GetColumnsForConceptTypeChild(conceptTypeChild, new List<ConceptTypeChild>())); + case AssimilationAbsorptionChoice.Absorb: + // Ignore this, it will be handled by this method when it is run for the absorbed concept type. + break; + case AssimilationAbsorptionChoice.Partition: + // Ignore this too. + break; + case AssimilationAbsorptionChoice.Separate: + // UNDONE: Handle separate here? If so, pull in the preferred identifier columns for the assimilated concept type if IsPreferredForParent is true. + break; } } - foreach (ConceptTypeChild assimilatedConceptType in preferredConceptTypeChildList) + foreach (ConceptTypeAssimilatesConceptType assimilation in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) { - if (assimilatedConceptType is ConceptTypeAssimilatesConceptType) + switch (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation)) { - columnsForConceptType.AddRange(GetColumnsForConceptTypeChild(assimilatedConceptType, new List<ConceptTypeChild>())); + case AssimilationAbsorptionChoice.Absorb: + // Ignore this too. + break; + case AssimilationAbsorptionChoice.Partition: + // Ignore this too. + break; + case AssimilationAbsorptionChoice.Separate: + // UNDONE: Handle separate here? If so, pull in the preferred identifier columns for the assimilator concept type if IsPreferredForTarget is true. + break; } } - // TESTING - UNDONE#1 -- Not needed, should be contained within the first Foreach - //foreach(ConceptTypeChild relatedConceptType in preferredConceptTypeChildList) + + + //foreach (ConceptTypeChild conceptTypeChild in ConceptTypeChild.GetLinksToTargetCollection(conceptType)) //{ - // if (relatedConceptTypeChild.GetType() == typeof(ConceptTypeRelatesToConceptType)) - // { - // columnsForConceptType.AddRange(GetColumnsForConceptTypeChild(relatedConceptType, new List<ConceptTypeChild>())); - // } + // columnsForConceptType.AddRange(GetColumnsForConceptTypeChild(conceptTypeChild, new List<ConceptTypeChild>())); //} - // END TESTING + Table conceptTypeTable = TableIsPrimarilyForConceptType.GetTable(conceptType); if (conceptTypeTable != null) { - foreach (Column column in columnsForConceptType) - { - Column possibleDuplicateColumn = CheckForDuplicateColumn(conceptTypeTable, column); - if (possibleDuplicateColumn != null) - { - if (preferredConceptTypeChildList.Contains(ColumnHasConceptTypeChild.GetConceptTypeChildPath(possibleDuplicateColumn)[0])) - { - // Record CTHasPrimaryIdentifierColumn(CT, "PossibleDuplicateColumn"); - } - } - else - { - if (preferredConceptTypeChildList.Contains(ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)[0])) - { - // Record CTHasPrimaryIdentifierColumn(CT, Column); - } - conceptTypeTable.ColumnCollection.Add(column); - } - } + conceptTypeTable.ColumnCollection.AddRange(columnsForConceptType); } else { - //ReadOnlyCollection<Table> tablesInvolvedWithConceptType = TableIsAlsoForConceptType.GetTable(conceptType); - //foreach (Table table in tablesInvolvedWithConceptType) - //{ - // foreach (Column column in columnsForConceptType) - // { - // // UNDONE: Why do we need to clone these here, where do we use it? - // Column clonedColumn = new Column(column.Store, new PropertyAssignment[] { new PropertyAssignment(Column.NameDomainPropertyId, column.Name) }); - // List<ConceptTypeChild> clonedConceptTypeChildPath = new List<ConceptTypeChild>(ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)); - - // AssimilationPath assimPath = new AssimilationPath(assimilationPath[table].Path); - - // int inumerator = 0; - - // foreach (ConceptTypeAssimilatesConceptType currentConceptTypeAssimilatesConceptType in assimPath.Path) - // { - // clonedConceptTypeChildPath.Insert(inumerator, (ConceptTypeChild)currentConceptTypeAssimilatesConceptType); - // inumerator++; - // } - - // Column possibleDuplicateColumn = CheckForDuplicateColumn(table.Table, clonedColumn); - // if (possibleDuplicateColumn == null) - // { - // // if CTC is in PreferredList - // // Record CTCHasPrimaryIdentifierColumn(CT, ClonedColumn); - // table.Table.ColumnCollection.Add(clonedColumn); - // } - // } - //} ReadOnlyCollection<TableIsAlsoForConceptType> tableIsAlsoForConceptTypeInvolvedWithConceptType = TableIsAlsoForConceptType.GetLinksToTable(conceptType); foreach (TableIsAlsoForConceptType tableIsAlsoForConceptType in tableIsAlsoForConceptTypeInvolvedWithConceptType) { @@ -600,21 +575,11 @@ { clonedConceptTypeChildPath.Add(assimilation); } - foreach (ConceptTypeChild child in ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)) - { - if (!clonedConceptTypeChildPath.Contains(child)) - { - clonedConceptTypeChildPath.Add(child); - } - } - //clonedConceptTypeChildPath.AddRange(ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)); + clonedConceptTypeChildPath.AddRange(ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)); Column possibleDuplicateColumn = CheckForDuplicateColumn(tableIsAlsoForConceptType.Table, clonedColumn); if (possibleDuplicateColumn == null) { - // if CTC is in PreferredList - // Record CTCHasPrimaryIdentifierColumn(CT, ClonedColumn); - tableIsAlsoForConceptType.Table.ColumnCollection.Add(clonedColumn); } else @@ -632,6 +597,88 @@ } } + private static Column GetColumnForInformationType(InformationType informationType, Stack<ConceptTypeChild> conceptTypeChildPath) + { + conceptTypeChildPath.Push(informationType); + Column column = new Column(informationType.Store, + new PropertyAssignment[]{ + new PropertyAssignment(Column.NameDomainPropertyId, informationType.Name)}); + ConceptTypeChild[] concpetTypeChildPathReverse = conceptTypeChildPath.ToArray(); + Array.Reverse(concpetTypeChildPathReverse); + ColumnHasConceptTypeChild.GetConceptTypeChildPath(column).AddRange(concpetTypeChildPathReverse); + conceptTypeChildPath.Pop(); + return column; + } + private static List<Column> GetColumnsForConceptTypeRelation(ConceptTypeRelatesToConceptType conceptTypeRelation, Stack<ConceptTypeChild> conceptTypeChildPath) + { + conceptTypeChildPath.Push(conceptTypeRelation); + List<Column> columns = GetPreferredIdentifierColumnsForConceptType(conceptTypeRelation.RelatedConceptType, conceptTypeChildPath); + conceptTypeChildPath.Pop(); + return columns; + } + + private static List<Column> GetPreferredIdentifierColumnsForConceptType(ConceptType conceptType, Stack<ConceptTypeChild> conceptTypeChildPath) + { + foreach (Uniqueness uniqueness in conceptType.UniquenessCollection) + { + if (uniqueness.IsPreferred) + { + LinkedElementCollection<ConceptTypeChild> uniquenessConceptTypeChildren = uniqueness.ConceptTypeChildCollection; + List<Column> columns = new List<Column>(uniquenessConceptTypeChildren.Count); + + foreach (ConceptTypeChild conceptTypeChild in uniquenessConceptTypeChildren) + { + InformationType informationType = conceptTypeChild as InformationType; + if (informationType != null) + { + columns.Add(GetColumnForInformationType(informationType, conceptTypeChildPath)); + } + else + { + Debug.Assert(conceptTypeChild is ConceptTypeRelatesToConceptType, "Uniquenesses can't contain ConceptTypeAssimilations."); + columns.AddRange(GetColumnsForConceptTypeRelation((ConceptTypeRelatesToConceptType)conceptTypeChild, conceptTypeChildPath)); + } + } + + return columns; + } + } + foreach (ConceptTypeAssimilatesConceptType assimilation in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) + { + if (assimilation.IsPreferredForTarget) + { + bool isAbsorb = (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) == AssimilationAbsorptionChoice.Absorb); + + conceptTypeChildPath.Push(assimilation); + + List<Column> columns = GetPreferredIdentifierColumnsForConceptType(assimilation.AssimilatorConceptType, conceptTypeChildPath); + + conceptTypeChildPath.Pop(); + + return columns; + } + } + foreach (ConceptTypeAssimilatesConceptType assimilation in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptType)) + { + if (assimilation.IsPreferredForParent) + { + bool isPartition = (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) == AssimilationAbsorptionChoice.Partition); + + conceptTypeChildPath.Push(assimilation); + + List<Column> columns = GetPreferredIdentifierColumnsForConceptType(assimilation.AssimilatedConceptType, conceptTypeChildPath); + + conceptTypeChildPath.Pop(); + + return columns; + } + } + Debug.Fail("Couldn't find preferred identifier for concept type."); + throw new InvalidOperationException(); + } + + + /// <summary> /// GetColumnsForConceptTypeChild gets the <see cref="Column"/> coresponding to a <see cref="ConceptTypeChild"/>. /// </summary> @@ -649,16 +696,15 @@ List<Column> columnList = new List<Column>(); conceptTypeChildPath.Add(conceptTypeChild); - if (conceptTypeChild.GetType() == typeof(InformationType)) + if (conceptTypeChild is InformationType) { Column informationTypeColumn = new Column(conceptTypeChild.Store, new PropertyAssignment[]{ new PropertyAssignment(Column.NameDomainPropertyId, conceptTypeChild.Name)}); - ColumnHasConceptTypeChild.GetConceptTypeChildPath(informationTypeColumn).Clear(); ColumnHasConceptTypeChild.GetConceptTypeChildPath(informationTypeColumn).AddRange(conceptTypeChildPath); columnList.Add(informationTypeColumn); } - else if (conceptTypeChild.GetType() == typeof(ConceptTypeRelatesToConceptType)) + else if (conceptTypeChild is ConceptTypeRelatesToConceptType) { ConceptType relatedConceptType = (ConceptType)conceptTypeChild.Target; @@ -667,7 +713,11 @@ { if (child == preferredList[preferredList.Count - 1]) { + columnList.AddRange(GetColumnsForConceptTypeChild(child, conceptTypeChildPath)); + + //conceptTypeChildPath.Clear(); + //columnList.AddRange(GetColumnsForConceptTypeChild(child, conceptTypeChildPath)); } else { @@ -677,7 +727,7 @@ } return columnList; } - else if (conceptTypeChild.GetType() == typeof(ConceptTypeAssimilatesConceptType)) + else if (conceptTypeChild is ConceptTypeAssimilatesConceptType) { ConceptType targetConceptType = (ConceptType)conceptTypeChild.Parent; List<ConceptTypeChild> preferredList = GetPreferredConceptTypeChildrenForConceptType(targetConceptType); @@ -744,64 +794,36 @@ /// </summary> private static List<ConceptTypeChild> GetPreferredConceptTypeChildrenForConceptType(ConceptType conceptType) { - List<ConceptTypeChild> prefferedConceptTypeChildrenList = new List<ConceptTypeChild>(); foreach (Uniqueness uniqueness in conceptType.UniquenessCollection) { if (uniqueness.IsPreferred) { - foreach (ConceptTypeChild childConceptType in uniqueness.ConceptTypeChildCollection) - { - prefferedConceptTypeChildrenList.Add(childConceptType); - } - break; + return new List<ConceptTypeChild>(uniqueness.ConceptTypeChildCollection); } } - if (prefferedConceptTypeChildrenList.Count == 0) + foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType + in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) { - foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType - in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) + if (conceptTypeAssimilatesConceptType.IsPreferredForTarget) { - if (conceptTypeAssimilatesConceptType.IsPreferredForTarget) - { - prefferedConceptTypeChildrenList.AddRange(GetPreferredConceptTypeChildrenForConceptType(conceptTypeAssimilatesConceptType.AssimilatorConceptType)); - break; - } + List<ConceptTypeChild> prefferedConceptTypeChildrenList = new List<ConceptTypeChild>(1); + prefferedConceptTypeChildrenList.Add(conceptTypeAssimilatesConceptType); + return prefferedConceptTypeChildrenList; } } - if (prefferedConceptTypeChildrenList.Count == 0) + foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType + in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptType)) { - foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType - in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptType)) + if (conceptTypeAssimilatesConceptType.IsPreferredForParent) { - if (conceptTypeAssimilatesConceptType.IsPreferredForParent) - { - prefferedConceptTypeChildrenList.Add(conceptTypeAssimilatesConceptType); - break; - } + List<ConceptTypeChild> prefferedConceptTypeChildrenList = new List<ConceptTypeChild>(1); + prefferedConceptTypeChildrenList.Add(conceptTypeAssimilatesConceptType); + return prefferedConceptTypeChildrenList; } } - // TESTING - if (prefferedConceptTypeChildrenList.Count == 0) - { - foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType - in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) - { - prefferedConceptTypeChildrenList.AddRange(GetPreferredConceptTypeChildrenForConceptType(conceptTypeAssimilatesConceptType.AssimilatorConceptType)); - break; - } - } - if (prefferedConceptTypeChildrenList.Count == 0) - { - foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType - in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptType)) - { - prefferedConceptTypeChildrenList.AddRange(GetPreferredConceptTypeChildrenForConceptType(conceptTypeAssimilatesConceptType.AssimilatedConceptType)); - break; - } - } - - return prefferedConceptTypeChildrenList; + Debug.Fail("Couldn't find preferred identifier."); + return null; } /// <summary> @@ -1080,7 +1102,7 @@ bool isPartitioned = false; foreach (ConceptTypeAssimilatesConceptType possiblePartition in childAssimilations) { - if (AssimilationMapping.GetAssimilationMappingFromAssimilation(possiblePartition).AbsorptionChoice == AssimilationAbsorptionChoice.Partition) + if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(possiblePartition) == AssimilationAbsorptionChoice.Partition) { isPartitioned = true; break; @@ -1222,7 +1244,6 @@ // UNDONE: Problem occuring with A is partitioned to B, C; C is partitioned to D, E. Setting A-C to Partition ReadOnlyCollection<ConceptTypeAssimilatesConceptType> childCollection = ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptTypeAssimilatesConceptType.AssimilatedConceptType); - /**/ bool containsPartitions = false; foreach (ConceptTypeAssimilatesConceptType act in childCollection) { @@ -1233,11 +1254,8 @@ break; } } - /**/ - /**/ if (!containsPartitions) { - /**/ Table targetTable = TableIsPrimarilyForConceptType.GetTable(conceptTypeAssimilatesConceptType.AssimilatedConceptType); foreach (Column target in targetTable.ColumnCollection) @@ -1250,7 +1268,6 @@ } } } - /**/ } else { @@ -1259,7 +1276,6 @@ columns.AddRange(ConceptTypeHasPrimaryIdentifierColumns(column, act.AssimilatedConceptType)); } } - /**/ } } @@ -1374,110 +1390,121 @@ /// <summary> /// FindTarget finds the target column for an input <see cref="ConceptType" />. /// </summary> - /// <param name="column">The <see cref="Column"/>.</param> - /// <param name="conceptType">The <see cref="ConceptType"/>.</param> + /// <param name="sourceColumn">The <see cref="Column"/>.</param> + /// <param name="targetConceptType">The <see cref="ConceptType"/>.</param> /// <returns>The target <see cref="Column"/>.</returns> - private static Column FindTarget(Column column, ConceptType conceptType) + private static Column FindTarget(Column sourceColumn, ConceptType targetConceptType) { - bool targetFound = true; - - if (TableIsPrimarilyForConceptType.GetTable(conceptType) == null) + Table targetTable = TableIsPrimarilyForConceptType.GetTable(targetConceptType); + TableIsAlsoForConceptType tableIsAlsoForConceptType; + if (targetTable == null) { - LinkedElementCollection<Table> tables = TableIsAlsoForConceptType.GetTable(conceptType); - if (tables.Count != 1) + ReadOnlyCollection<TableIsAlsoForConceptType> tableIsAlsoForConceptTypeLinks = TableIsAlsoForConceptType.GetLinksToTable(targetConceptType); + if (tableIsAlsoForConceptTypeLinks.Count != 1) { return null; } + else + { + tableIsAlsoForConceptType = tableIsAlsoForConceptTypeLinks[0]; + targetTable = tableIsAlsoForConceptType.Table; + } } + else + { + tableIsAlsoForConceptType = null; + } - //LinkedElementCollection<ConceptType> relating = ConceptTypeRelatesToConceptType.GetRelatingConceptTypeCollection(conceptType); - //int relatingCount = relating.Count; - //ConceptType[] real = new ConceptType[] { relatingCount }; - //relating.CopyTo(real, 0); - List<Column> possibleColumns = ConceptTypeHasPrimaryIdentifierColumns(column, conceptType); - - foreach (Column targetColumn in possibleColumns) + LinkedElementCollection<ConceptTypeChild> sourceCtcPath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(sourceColumn); + List<ConceptTypeChild> targetCtcPath = new List<ConceptTypeChild>(sourceCtcPath.Count); + + // This handles removing the source concept type's assimilation path, + // and the relationship itself. + // UNDONE: Can the relationship portion of this ever have more than one CTC in it? If so, this will break badly. + bool finishedWithAssimilationPath = false; + bool copyPath = false; + for (int i = 0; i < sourceCtcPath.Count; i++) { - targetFound = true; - - if (targetColumn.Equals(column)) + ConceptTypeChild currentSourcePathChild = sourceCtcPath[i]; + if (copyPath) { - targetFound = false; + targetCtcPath.Add(currentSourcePathChild); } else { - //for (int i = 0; i < ColumnHasConceptTypeChild.GetConceptTypeChildPath(targetColumn).Count; ++i) - //{ - LinkedElementCollection<ConceptTypeChild> leftPath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column); - LinkedElementCollection<ConceptTypeChild> rightPath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(targetColumn); - - int leftBuffer = 0; - int rightBuffer = 0; - - if (rightPath[0].GetType() == typeof(ConceptTypeAssimilatesConceptType)) + if (!finishedWithAssimilationPath) { - if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(rightPath[0] as ConceptTypeAssimilatesConceptType) == AssimilationAbsorptionChoice.Separate) + ConceptTypeAssimilatesConceptType currentAssimilation = currentSourcePathChild as ConceptTypeAssimilatesConceptType; + if (currentAssimilation != null) { - rightBuffer += 1; + if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(currentAssimilation) != AssimilationAbsorptionChoice.Separate) + { + continue; + } } + finishedWithAssimilationPath = true; } - if (leftPath[0].GetType() == typeof(ConceptTypeAssimilatesConceptType)) + if (currentSourcePathChild.Target == targetConceptType) { - if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(leftPath[0] as ConceptTypeAssimilatesConceptType) == AssimilationAbsorptionChoice.Separate) - { - leftBuffer += 1; - } + // This is the end of the assimilations and we're now at the start of the path to the preferred identifier. + copyPath = true; } + } + } - if (leftPath.Count - leftBuffer >= rightPath.Count - rightBuffer) - { - for (int reverseIndex = 0; reverseIndex < rightPath.Count - rightBuffer; reverseIndex++) - { - if (rightPath[rightPath.Count - 1 - reverseIndex] != leftPath[leftPath.Count - 1 - reverseIndex]) - { - targetFound = false; - break; - } + if (tableIsAlsoForConceptType != null) + { + LinkedElementCollection<ConceptTypeAssimilatesConceptType> targetAssimilationPath = TableIsAlsoForConceptTypeHasAssimilationPath.GetAssimilationPath(tableIsAlsoForConceptType); + InformationType informationType = (InformationType)sourceCtcPath[sourceCtcPath.Count - 1]; + ConceptType informationTypeParent = informationType.Parent; - } - } - else + // Remove everything at and after index, and add everything before it + int index; + for (index = 0; index < targetAssimilationPath.Count; index++) + { + if (targetAssimilationPath[index].Parent == informationTypeParent) { - for (int reverseIndex = 0; reverseIndex < leftPath.Count - leftBuffer; reverseIndex++) - { - if (leftPath[leftPath.Count - 1 - reverseIndex] != rightPath[rightPath.Count - 1 - reverseIndex]) - { - targetFound = false; - break; - } - } + break; } - //} - // END TEST + } +#if DEBUG + for (int i = targetAssimilationPath.Count - 1, j = 0; i >= index; i--, j++) + { + Debug.Assert(targetCtcPath[j] == targetAssimilationPath[i]); + } +#endif //DEBUG - //if ((i + 1 < leftPath.Count && i + offset < rightPath.Count && - // leftPath[i + 1] != rightPath[i + offset])) - //{ - // for (int j = 0; j < leftPath.Count; ++j) - // { - // if (leftPath[j].GetType() == typeof(InformationType)) - // { - // offset = j; - // } - // } + targetCtcPath.RemoveRange(0, targetAssimilationPath.Count - index); - // if ((i + 1 < leftPath.Count && i + offset < rightPath.Count && - // rightPath[rightPath.Count - 1] != rightPath[offset])) - // { + for (int i = index - 1; i >= 0; i--) + { + targetCtcPath.Insert(0, targetAssimilationPath[i]); + } + } - // targetFound = false; - // break; - // } - //} + foreach (Column possibleColumn in targetTable.ColumnCollection) + { + if (possibleColumn == sourceColumn) + { + continue; } - if (targetFound && targetColumn.Table != null) + bool isMatch = true; + LinkedElementCollection<ConceptTypeChild> possibleCtcPath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(possibleColumn); + + if (possibleCtcPath.Count == targetCtcPath.Count) { - return targetColumn; + for (int i = targetCtcPath.Count - 1; i >= 0; i--) + { + if (possibleCtcPath[i] != targetCtcPath[i]) + { + isMatch = false; + break; + } + } + if (isMatch) + { + return possibleColumn; + } } } @@ -1526,7 +1553,7 @@ foreach (TableIsAlsoForConceptType tableIsAlsoForConceptType in TableIsAlsoForConceptType.GetLinksToTable(conceptType)) { Table table = tableIsAlsoForConceptType.Table; - LinkedElementCollection<Column> columns = table.ColumnCollection; + LinkedElementCollection<Column> tableColumns = table.ColumnCollection; LinkedElementCollection<ConceptTypeAssimilatesConceptType> assimilationPath = tableIsAlsoForConceptType.AssimilationPath; int assimilationPathCount = assimilationPath.Count; @@ -1535,6 +1562,7 @@ UniquenessConstraint uniquenessConstraint = new UniquenessConstraint(table.Store, new PropertyAssignment[] { new PropertyAssignment(UniquenessConstraint.NameDomainPropertyId, uniqueness.Name) }); uniquenessConstraint.Table = table; new UniquenessConstraintIsForUniqueness(uniquenessConstraint, uniqueness); + LinkedElementCollection<Column> uniquenessColumns = uniquenessConstraint.ColumnCollection; bool isPreferred = uniqueness.IsPreferred; if (isPreferred) @@ -1568,10 +1596,10 @@ List<Column> matchingColumns = new List<Column>(uniquenessConceptTypeChildren.Count); - foreach (Column column in columns) + foreach (Column column in tableColumns) { LinkedElementCollection<ConceptTypeChild> ctcPath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column); - bool pathMatches = ctcPath.Count == assimilationPathCount + 1; + bool pathMatches = ctcPath.Count >= assimilationPathCount + 1; if (pathMatches) { for (int i = 0; i < assimilationPathCount; i++) @@ -1589,7 +1617,7 @@ } } - Debug.Assert(matchingColumns.Count == uniquenessConceptTypeChildren.Count); + Debug.Assert(matchingColumns.Count >= uniquenessConceptTypeChildren.Count); foreach (ConceptTypeChild conceptTypeChild in uniqueness.ConceptTypeChildCollection) { @@ -1598,9 +1626,8 @@ Column column = matchingColumns[i]; if (ColumnHasConceptTypeChild.GetConceptTypeChildPath(column)[assimilationPathCount] == conceptTypeChild) { - uniquenessConstraint.ColumnCollection.Add(column); + uniquenessColumns.Add(column); matchingColumns.RemoveAt(i); - break; } } } Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.dsl =================================================================== --- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.dsl 2007-09-10 23:03:11 UTC (rev 1118) +++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.dsl 2007-09-10 23:04:41 UTC (rev 1119) @@ -253,7 +253,7 @@ </DomainRole> </Target> </DomainRelationship> - <DomainRelationship Id="CCBCAB63-ADE4-43FA-8E29-8A598B0969F5" Name="ColumnHasConceptTypeChild" Namespace="Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge"> + <DomainRelationship Id="CCBCAB63-ADE4-43FA-8E29-8A598B0969F5" Name="ColumnHasConceptTypeChild" Namespace="Neumont.Tools.ORMAbstractionToConceptualDatabaseBridge" AllowsDuplicates="true"> <Source> <DomainRole Id="BC7EA8A8-8772-4CA4-B914-B78B4B583338" Description="" Name="Column" PropertyName="ConceptTypeChildPath" Multiplicity="OneMany"> <RolePlayer> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 22:57:08
|
Revision: 1116 http://orm.svn.sourceforge.net/orm/?rev=1116&view=rev Author: mcurland Date: 2007-09-10 15:57:11 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Temporary workaround to 'independent object types should not have implied mandatory roles'. Ignore single role implied mandatories on independent object types. The full fix is much riskier and will be done in the future. refs #330 Modified Paths: -------------- trunk/ORMModel/ObjectModel/Role.cs Modified: trunk/ORMModel/ObjectModel/Role.cs =================================================================== --- trunk/ORMModel/ObjectModel/Role.cs 2007-09-10 22:55:47 UTC (rev 1115) +++ trunk/ORMModel/ObjectModel/Role.cs 2007-09-10 22:57:11 UTC (rev 1116) @@ -182,7 +182,11 @@ case ConstraintType.ImpliedMandatory: if (roleSequence.RoleCollection.Count == 1) { - return (MandatoryConstraint)constraint; + MandatoryConstraint mandatoryConstraint = (MandatoryConstraint)constraint; + ObjectType objectType; + return (null != (objectType = mandatoryConstraint.ImpliedByObjectType) && objectType.IsIndependent) ? + null : + mandatoryConstraint; } break; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 22:55:44
|
Revision: 1115 http://orm.svn.sourceforge.net/orm/?rev=1115&view=rev Author: mcurland Date: 2007-09-10 15:55:47 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Removed assertion (yes, it can be something other than 1). refs #327 Modified Paths: -------------- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs Modified: trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs =================================================================== --- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-09-10 22:54:09 UTC (rev 1114) +++ trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-09-10 22:55:47 UTC (rev 1115) @@ -1033,8 +1033,6 @@ LinkedElementCollection<ConceptTypeChild> childrenForFactType = ConceptTypeChildHasPathFactType.GetConceptTypeChild(factType); - Debug.Assert(childrenForFactType.Count == 1, "Can this not be 1?"); - associationChildren.AddRange(ConceptTypeChildHasPathFactType.GetConceptTypeChild(factType)); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 22:54:06
|
Revision: 1114 http://orm.svn.sourceforge.net/orm/?rev=1114&view=rev Author: mcurland Date: 2007-09-10 15:54:09 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Stop offering absorb choice on ObjectType in some cases where choosing the absorb will throw. Also changed Absorbed to display as 'Absorbed (All Paths)' to emphasize that we are not absorbing over the primary path only. refs #334 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/AssimilationMapping.cs trunk/RelationalModel/OialDcilBridge/MappingCustomizationModel.resx Modified: trunk/RelationalModel/OialDcilBridge/AssimilationMapping.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/AssimilationMapping.cs 2007-09-10 22:52:52 UTC (rev 1113) +++ trunk/RelationalModel/OialDcilBridge/AssimilationMapping.cs 2007-09-10 22:54:09 UTC (rev 1114) @@ -505,9 +505,9 @@ { return canPartition ? PartitionablePartitionedChildValues : PartitionedChildValues; } - if (customAbsorb || (!seenAbsorb && null != AssimilatorTracker.GetNearestAbsorbingAssimilatorConceptType(assimilations, true, null))) + if (customAbsorb || !seenAbsorb) { - fullAbsorbAvailable = true; + fullAbsorbAvailable = null != AssimilatorTracker.GetNearestAbsorbingAssimilatorConceptType(assimilations, true, null); } else if (seenAbsorb) { Modified: trunk/RelationalModel/OialDcilBridge/MappingCustomizationModel.resx =================================================================== --- trunk/RelationalModel/OialDcilBridge/MappingCustomizationModel.resx 2007-09-10 22:52:52 UTC (rev 1113) +++ trunk/RelationalModel/OialDcilBridge/MappingCustomizationModel.resx 2007-09-10 22:54:09 UTC (rev 1114) @@ -166,7 +166,7 @@ <comment>The display name for the AbsorptionChoice property on an ObjectType. Displays as the name of a property in the Properties Window.</comment> </data> <data name="ObjectTypeAbsorptionChoice.Absorbed" xml:space="preserve"> - <value>Absorbed</value> + <value>Absorbed (All Paths)</value> <comment>The ObjectType is absorbed through all paths.</comment> </data> <data name="ObjectTypeAbsorptionChoice.CustomAbsorbed" xml:space="preserve"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 22:52:53
|
Revision: 1113 http://orm.svn.sourceforge.net/orm/?rev=1113&view=rev Author: mcurland Date: 2007-09-10 15:52:52 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Fixes some bugs with name generation. refs #334 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs trunk/RelationalModel/OialDcilBridge/NameGeneration.cs Modified: trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs 2007-09-10 22:50:51 UTC (rev 1112) +++ trunk/RelationalModel/OialDcilBridge/ModificationTracker.cs 2007-09-10 22:52:52 UTC (rev 1113) @@ -214,10 +214,27 @@ ORMCore.FactType factType = ((ORMCore.Role)e.ModelElement).FactType; if (factType != null) { - foreach (ConceptTypeChild child in ConceptTypeChildHasPathFactType.GetConceptTypeChild(factType)) + ORMCore.Objectification objectification = factType.Objectification; + if (objectification != null) { - ValidateConceptTypeChildNameChanged(child); + foreach (ORMCore.FactType impliedFactType in objectification.ImpliedFactTypeCollection) + { + foreach (ConceptTypeChild child in ConceptTypeChildHasPathFactType.GetConceptTypeChild(impliedFactType)) + { + ValidateConceptTypeChildNameChanged(child); + goto doubleBreak; + } + } + doubleBreak: ; } + else + { + foreach (ConceptTypeChild child in ConceptTypeChildHasPathFactType.GetConceptTypeChild(factType)) + { + ValidateConceptTypeChildNameChanged(child); + break; + } + } } } } Modified: trunk/RelationalModel/OialDcilBridge/NameGeneration.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-10 22:50:51 UTC (rev 1112) +++ trunk/RelationalModel/OialDcilBridge/NameGeneration.cs 2007-09-10 22:52:52 UTC (rev 1113) @@ -166,11 +166,11 @@ { foreach (ConceptType conceptType in secondaryConceptTypes) { - name.Append(conceptType.Name); if (longerThan == null || FinalizeName(name.ToString(), tableCase, tableStringReplace) != longerThan) { break; } + name.Append(conceptType.Name); } } @@ -180,9 +180,12 @@ } string finalName = FinalizeName(name.ToString(), tableCase, tableStringReplace); - while (finalName == longerThan) + if (longerThan != null && finalName == longerThan.TrimEnd('_')) { - finalName += "_"; + while (finalName.Length <= longerThan.Length) + { + finalName += "_"; + } } return finalName; } @@ -212,6 +215,8 @@ //get a role name for each fact type, or generate one from the reading foreach (FactType factType in factTypes) { + //factType.ImpliedByObjectification + //factType.Objectification.ImpliedFactTypeCollection string roleName; LinkedElementCollection<RoleBase> factTypeRoles = factType.RoleCollection; int? unaryRoleIndex = FactType.GetUnaryRoleIndex(factTypeRoles); @@ -292,6 +297,7 @@ if (!hasUnary || (longerThan != null && longerThan == FinalizeName(name.ToString(), columnCasing, columnStringReplace))) { + string curName; if (!(hasRoleOrHyphenBound || alwaysKeepText) && (predicateTextCount == 1 && (longerThan == null || longerThan != FinalizeName(valueTypeName, columnCasing, columnStringReplace)))) { @@ -299,7 +305,8 @@ name.Remove(0, name.Length); name.Append(valueTypeName); } - else if (!hasRoleOrHyphenBound || FinalizeName(name.ToString(), columnCasing, columnStringReplace) == longerThan) + else if (!hasRoleOrHyphenBound || (longerThan != null && (FinalizeName(curName = name.ToString(), columnCasing, columnStringReplace) == longerThan + || FinalizeName(curName + valueTypeName, columnCasing, columnStringReplace) == longerThan))) { name.Append(valueTypeName); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-09-10 22:50:48
|
Revision: 1112 http://orm.svn.sourceforge.net/orm/?rev=1112&view=rev Author: mcurland Date: 2007-09-10 15:50:51 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Added delete propagation to ReferenceConstraint and so that on reloading of the model we don't retain non-bound foreign keys. Implemented a change in the Oial Model to better check on a UniquenessConstraint if all children map towards the appropriate ObjectType. refs #327. Added additional code into the handling of separations so that when a separation is acting on a ConceptType that is being partitioned into assimilated ConceptTypes, it properly maps to them. refs #328. Modified Paths: -------------- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs trunk/RelationalModel/DcilModel/DcilModel.dsl trunk/RelationalModel/DcilModel/GeneratedCode/DomainModel.cs trunk/RelationalModel/DcilModel/GeneratedCode/DomainRelationships.cs trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs Modified: trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs =================================================================== --- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-09-01 19:13:42 UTC (rev 1111) +++ trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-09-10 22:50:51 UTC (rev 1112) @@ -936,7 +936,7 @@ } FactTypeMapping factTypeMapping = factTypeMappings[binarizedFactType]; - if (factTypeMapping.TowardsObjectType != objectType) + if (factTypeMapping.TowardsRole != childRole.OppositeRoleAlwaysResolveProxy.Role) { allChildrenMapTowardObjectType = false; break; Modified: trunk/RelationalModel/DcilModel/DcilModel.dsl =================================================================== --- trunk/RelationalModel/DcilModel/DcilModel.dsl 2007-09-01 19:13:42 UTC (rev 1111) +++ trunk/RelationalModel/DcilModel/DcilModel.dsl 2007-09-10 22:50:51 UTC (rev 1112) @@ -544,7 +544,7 @@ </DomainRole> </Source> <Target> - <DomainRole Id="6DAA73B4-E37E-4BE1-BB3C-DAFBCFD51343" Name="ReferenceConstraint" PropertyName="SourceTable" Multiplicity="One"> + <DomainRole Id="6DAA73B4-E37E-4BE1-BB3C-DAFBCFD51343" Name="ReferenceConstraint" PropertyName="SourceTable" Multiplicity="One" PropagatesDelete="true"> <RolePlayer> <DomainClassMoniker Name="ReferenceConstraint"/> </RolePlayer> @@ -653,7 +653,7 @@ </DomainRole> </Source> <Target> - <DomainRole Id="32200848-28E3-4D35-9A61-F592903B52BF" Name="Column" IsPropertyGenerator="false" Multiplicity="ZeroMany"> + <DomainRole Id="32200848-28E3-4D35-9A61-F592903B52BF" Name="Column" PropertyName="UniquenessConstraints" IsPropertyGenerator="false" Multiplicity="ZeroMany"> <RolePlayer> <DomainClassMoniker Name="Column"/> </RolePlayer> @@ -670,14 +670,14 @@ </ClrAttribute> </Attributes> <Source> - <DomainRole Id="22F748A4-8086-46C4-A323-E93574438D16" Name="ReferenceConstraint" PropertyName="TargetTable" Multiplicity="One"> + <DomainRole Id="22F748A4-8086-46C4-A323-E93574438D16" Name="ReferenceConstraint" PropertyName="TargetTable" Multiplicity="One" PropagatesDelete="true"> <RolePlayer> <DomainClassMoniker Name="ReferenceConstraint"/> </RolePlayer> </DomainRole> </Source> <Target> - <DomainRole Id="3EFFDDB4-4B20-4EB4-8A79-271240574413" Name="TargetTable" IsPropertyGenerator="false" Multiplicity="ZeroMany"> + <DomainRole Id="3EFFDDB4-4B20-4EB4-8A79-271240574413" Name="TargetTable" PropertyName="ReferenceConstraints" IsPropertyGenerator="false" Multiplicity="ZeroMany"> <RolePlayer> <DomainClassMoniker Name="Table"/> </RolePlayer> Modified: trunk/RelationalModel/DcilModel/GeneratedCode/DomainModel.cs =================================================================== --- trunk/RelationalModel/DcilModel/GeneratedCode/DomainModel.cs 2007-09-01 19:13:42 UTC (rev 1111) +++ trunk/RelationalModel/DcilModel/GeneratedCode/DomainModel.cs 2007-09-10 22:50:51 UTC (rev 1112) @@ -409,9 +409,11 @@ DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsColumn.ColumnDomainRoleId, true); DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsConstraint.ConstraintDomainRoleId, true); DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsUniquenessConstraint.UniquenessConstraintDomainRoleId, true); + DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsReferenceConstraint.ReferenceConstraintDomainRoleId, true); DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsCheckConstraint.CheckConstraintDomainRoleId, true); DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.DomainContainsCheckConstraint.CheckConstraintDomainRoleId, true); DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasPredefinedDataType.PredefinedDataTypeDomainRoleId, true); + DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ReferenceConstraintTargetsTable.ReferenceConstraintDomainRoleId, true); DomainRoles.Add(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ReferenceConstraintContainsColumnReference.ColumnReferenceDomainRoleId, true); #endregion } Modified: trunk/RelationalModel/DcilModel/GeneratedCode/DomainRelationships.cs =================================================================== --- trunk/RelationalModel/DcilModel/GeneratedCode/DomainRelationships.cs 2007-09-01 19:13:42 UTC (rev 1111) +++ trunk/RelationalModel/DcilModel/GeneratedCode/DomainRelationships.cs 2007-09-10 22:50:51 UTC (rev 1112) @@ -1800,7 +1800,7 @@ /// </summary> [DslDesign::DisplayNameResource("Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsReferenceConstraint/ReferenceConstraint.DisplayName", typeof(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ConceptualDatabaseDomainModel), "Neumont.Tools.RelationalModels.ConceptualDatabase.GeneratedCode.DomainModelResx")] [DslDesign::DescriptionResource("Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsReferenceConstraint/ReferenceConstraint.Description", typeof(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ConceptualDatabaseDomainModel), "Neumont.Tools.RelationalModels.ConceptualDatabase.GeneratedCode.DomainModelResx")] - [DslModeling::DomainRole(DslModeling::DomainRoleOrder.Target, PropertyName = "SourceTable", PropertyDisplayNameKey="Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsReferenceConstraint/ReferenceConstraint.PropertyDisplayName", Multiplicity = DslModeling::Multiplicity.One)] + [DslModeling::DomainRole(DslModeling::DomainRoleOrder.Target, PropertyName = "SourceTable", PropertyDisplayNameKey="Neumont.Tools.RelationalModels.ConceptualDatabase.TableContainsReferenceConstraint/ReferenceConstraint.PropertyDisplayName", PropagatesDelete = true, Multiplicity = DslModeling::Multiplicity.One)] [DslModeling::DomainObjectId("6daa73b4-e37e-4be1-bb3c-dafbcfd51343")] public virtual ReferenceConstraint ReferenceConstraint { @@ -2551,13 +2551,13 @@ } #endregion - #region Static methods to access Columns of a Domain + #region Static methods to access columns of a Domain /// <summary> - /// Gets a list of Columns. + /// Gets a list of columns. /// </summary> [global::System.Diagnostics.DebuggerStepThrough] [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011")] - public static DslModeling::LinkedElementCollection<Column> GetColumns(Domain element) + public static DslModeling::LinkedElementCollection<Column> Getcolumns(Domain element) { return new DslModeling::LinkedElementCollection<Column>(element, DomainDomainRoleId); } @@ -2576,7 +2576,7 @@ /// </summary> [DslDesign::DisplayNameResource("Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain/Domain.DisplayName", typeof(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ConceptualDatabaseDomainModel), "Neumont.Tools.RelationalModels.ConceptualDatabase.GeneratedCode.DomainModelResx")] [DslDesign::DescriptionResource("Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain/Domain.Description", typeof(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ConceptualDatabaseDomainModel), "Neumont.Tools.RelationalModels.ConceptualDatabase.GeneratedCode.DomainModelResx")] - [DslModeling::DomainRole(DslModeling::DomainRoleOrder.Target, PropertyName = "Columns", PropertyDisplayNameKey="Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain/Domain.PropertyDisplayName", Multiplicity = DslModeling::Multiplicity.ZeroMany)] + [DslModeling::DomainRole(DslModeling::DomainRoleOrder.Target, PropertyName = "columns", PropertyDisplayNameKey="Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain/Domain.PropertyDisplayName", Multiplicity = DslModeling::Multiplicity.ZeroMany)] [DslModeling::DomainObjectId("8049efc1-7e4f-4965-82e7-d0b376424c57")] public virtual Domain Domain { @@ -2640,7 +2640,7 @@ /// </summary> [global::System.Diagnostics.DebuggerStepThrough] [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011")] - public static global::System.Collections.ObjectModel.ReadOnlyCollection<global::Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain> GetLinksToColumns ( global::Neumont.Tools.RelationalModels.ConceptualDatabase.Domain domainInstance ) + public static global::System.Collections.ObjectModel.ReadOnlyCollection<global::Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain> GetLinksTocolumns ( global::Neumont.Tools.RelationalModels.ConceptualDatabase.Domain domainInstance ) { return DslModeling::DomainRoleInfo.GetElementLinks<global::Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain>(domainInstance, global::Neumont.Tools.RelationalModels.ConceptualDatabase.ColumnHasDomain.DomainDomainRoleId); } @@ -3519,7 +3519,7 @@ /// </summary> [DslDesign::DisplayNameResource("Neumont.Tools.RelationalModels.ConceptualDatabase.ReferenceConstraintTargetsTable/ReferenceConstraint.DisplayName", typeof(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ConceptualDatabaseDomainModel), "Neumont.Tools.RelationalModels.ConceptualDatabase.GeneratedCode.DomainModelResx")] [DslDesign::DescriptionResource("Neumont.Tools.RelationalModels.ConceptualDatabase.ReferenceConstraintTargetsTable/ReferenceConstraint.Description", typeof(global::Neumont.Tools.RelationalModels.ConceptualDatabase.ConceptualDatabaseDomainModel), "Neumont.Tools.RelationalModels.ConceptualDatabase.GeneratedCode.DomainModelResx")] - [DslModeling::DomainRole(DslModeling::DomainRoleOrder.Source, PropertyName = "TargetTable", PropertyDisplayNameKey="Neumont.Tools.RelationalModels.ConceptualDatabase.ReferenceConstraintTargetsTable/ReferenceConstraint.PropertyDisplayName", Multiplicity = DslModeling::Multiplicity.One)] + [DslModeling::DomainRole(DslModeling::DomainRoleOrder.Source, PropertyName = "TargetTable", PropertyDisplayNameKey="Neumont.Tools.RelationalModels.ConceptualDatabase.ReferenceConstraintTargetsTable/ReferenceConstraint.PropertyDisplayName", PropagatesDelete = true, Multiplicity = DslModeling::Multiplicity.One)] [DslModeling::DomainObjectId("22f748a4-8086-46c4-a323-e93574438d16")] public virtual ReferenceConstraint ReferenceConstraint { Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-01 19:13:42 UTC (rev 1111) +++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-10 22:50:51 UTC (rev 1112) @@ -511,11 +511,9 @@ List<ConceptTypeChild> preferredConceptTypeChildList = GetPreferredConceptTypeChildrenForConceptType(conceptType); List<Column> columnsForConceptType = new List<Column>(); - List<ConceptTypeChild> tester = new List<ConceptTypeChild>(); foreach (ConceptTypeChild conceptTypeChild in ConceptTypeChild.GetLinksToTargetCollection(conceptType)) { - tester.Add(conceptTypeChild); if (!(conceptTypeChild is ConceptTypeAssimilatesConceptType)) { columnsForConceptType.AddRange(GetColumnsForConceptTypeChild(conceptTypeChild, new List<ConceptTypeChild>())); @@ -1075,6 +1073,29 @@ } } } + else + { + // If the seperation is further partitioned then it will not have a secondary child table, further assimilations or seperations are ok though. + ReadOnlyCollection<ConceptTypeAssimilatesConceptType> childAssimilations = ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(assimilation.AssimilatedConceptType); + bool isPartitioned = false; + foreach (ConceptTypeAssimilatesConceptType possiblePartition in childAssimilations) + { + if (AssimilationMapping.GetAssimilationMappingFromAssimilation(possiblePartition).AbsorptionChoice == AssimilationAbsorptionChoice.Partition) + { + isPartitioned = true; + break; + } + } + if (isPartitioned) + { + bool prefered = false; + foreach (ConceptTypeAssimilatesConceptType partition in childAssimilations) + { + DoSeparation(partition, ref prefered); + prefered = false; + } + } + } } /// <summary> @@ -1198,18 +1219,47 @@ } else if (AssimilationMapping.GetAbsorptionChoiceFromAssimilation(conceptTypeAssimilatesConceptType) == AssimilationAbsorptionChoice.Separate) { - Table targetTable = TableIsPrimarilyForConceptType.GetTable(conceptTypeAssimilatesConceptType.AssimilatedConceptType); + // UNDONE: Problem occuring with A is partitioned to B, C; C is partitioned to D, E. Setting A-C to Partition + ReadOnlyCollection<ConceptTypeAssimilatesConceptType> childCollection = ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptTypeAssimilatesConceptType.AssimilatedConceptType); - foreach (Column target in targetTable.ColumnCollection) + /**/ + bool containsPartitions = false; + foreach (ConceptTypeAssimilatesConceptType act in childCollection) { - foreach (ConceptTypeChild conceptTypeChild in ColumnHasConceptTypeChild.GetConceptTypeChildPath(target)) + if (AssimilationMapping.GetAssimilationMappingFromAssimilation(act).AbsorptionChoice == AssimilationAbsorptionChoice.Partition) { - if (ColumnHasConceptTypeChild.GetConceptTypeChildPath(target).Contains(conceptTypeChild) && target != column) + + containsPartitions = true; + break; + } + } + /**/ + /**/ + if (!containsPartitions) + { + /**/ + Table targetTable = TableIsPrimarilyForConceptType.GetTable(conceptTypeAssimilatesConceptType.AssimilatedConceptType); + + foreach (Column target in targetTable.ColumnCollection) + { + foreach (ConceptTypeChild conceptTypeChild in ColumnHasConceptTypeChild.GetConceptTypeChildPath(target)) { - columns.Add(target); + if (ColumnHasConceptTypeChild.GetConceptTypeChildPath(target).Contains(conceptTypeChild) && target != column) + { + columns.Add(target); + } } } + /**/ } + else + { + foreach (ConceptTypeAssimilatesConceptType act in childCollection) + { + columns.AddRange(ConceptTypeHasPrimaryIdentifierColumns(column, act.AssimilatedConceptType)); + } + } + /**/ } } @@ -1440,9 +1490,11 @@ /// <param name="conceptType">The <see cref="ConceptType"/>.</param> private static void CreateUniquenessConstraints(ConceptType conceptType) { + // UNDONE: Look here for possible problems with ring contstraints Table isPrimarilyForTable = TableIsPrimarilyForConceptType.GetTable(conceptType); if (isPrimarilyForTable != null) { + List<Uniqueness> alreadyDone = new List<Uniqueness>(); foreach (Uniqueness uniqueness in conceptType.UniquenessCollection) { UniquenessConstraint uniquenessConstraint = new UniquenessConstraint(uniqueness.Store, new PropertyAssignment[] { new PropertyAssignment(UniquenessConstraint.NameDomainPropertyId, uniqueness.Name) }); 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:13:55
|
Revision: 1111 http://orm.svn.sourceforge.net/orm/?rev=1111&view=rev Author: mcurland Date: 2007-09-01 12:13:42 -0700 (Sat, 01 Sep 2007) Log Message: ----------- Removed temporary crash workaround from [1106] refs #334 Modified Paths: -------------- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs Modified: trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs =================================================================== --- trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-01 19:12:14 UTC (rev 1110) +++ trunk/RelationalModel/OialDcilBridge/OialDcilBridge.DeserializationFixupListeners.cs 2007-09-01 19:13:42 UTC (rev 1111) @@ -42,7 +42,6 @@ } public partial class ORMAbstractionToConceptualDatabaseBridgeDomainModel : IDeserializationFixupListenerProvider { - private const bool AllowIsPreferredForTarget = true; #region Fully populate from OIAL #region AssimilationPath class @@ -764,7 +763,7 @@ foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) { - if (AllowIsPreferredForTarget && conceptTypeAssimilatesConceptType.IsPreferredForTarget) + if (conceptTypeAssimilatesConceptType.IsPreferredForTarget) { prefferedConceptTypeChildrenList.AddRange(GetPreferredConceptTypeChildrenForConceptType(conceptTypeAssimilatesConceptType.AssimilatorConceptType)); break; @@ -837,7 +836,7 @@ TableIsPrimarilyForConceptType.GetTable(assimilation.AssimilatorConceptType).UniquenessConstraintCollection.Add(mappedConstraint); } - else if (AllowIsPreferredForTarget && assimilation.IsPreferredForTarget) + else if (assimilation.IsPreferredForTarget) { if (isPreferredForChildFound == false) { @@ -1153,7 +1152,7 @@ } foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilatesConceptType in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatorConceptTypeCollection(conceptType)) { - if (AllowIsPreferredForTarget && conceptTypeAssimilatesConceptType.IsPreferredForTarget) + if (conceptTypeAssimilatesConceptType.IsPreferredForTarget) { foreach (Column target in ColumnHasConceptTypeChild.GetColumn((ConceptTypeChild)conceptTypeAssimilatesConceptType)) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |