/// <summary>
 /// This recursive method will migrate new nodes from sourceNode into destinationNode node
 /// </summary>
 private static void MigrateNewChildNodesAndOptionsInto(ConfigurableDictionaryNode destinationNode, ConfigurableDictionaryNode sourceNode)
 {
     // REVIEW (Hasso) 2017.03: If this is a NoteInParaStyles node: Rather than overwriting the user's Options, copy their Options into a new WS&ParaOptions
     if ((destinationNode.DictionaryNodeOptions == null || DictionaryConfigurationModel.NoteInParaStyles.Contains(sourceNode.FieldDescription)) &&
         sourceNode.DictionaryNodeOptions != null)
     {
         destinationNode.DictionaryNodeOptions = sourceNode.DictionaryNodeOptions;
     }
     EnsureCssOverrideAndStylesAreUpdated(destinationNode, sourceNode);
     // LT-18286: don't merge direct children into sharing parents.
     if (destinationNode.ReferencedNode != null || destinationNode.Children == null || sourceNode.Children == null)
     {
         return;
     }
     // First recurse into each matching child node
     foreach (var newChild in sourceNode.Children)
     {
         var matchFromDestination = FindMatchingChildNode(newChild.Label, destinationNode.Children);
         if (matchFromDestination != null)
         {
             MigrateNewChildNodesAndOptionsInto(matchFromDestination, newChild);
         }
         else
         {
             var indexOfNewChild = sourceNode.Children.FindIndex(n => n.Label == newChild.Label);
             InsertNewNodeIntoOldConfig(destinationNode, newChild.DeepCloneUnderParent(destinationNode, true), sourceNode, indexOfNewChild);
         }
     }
 }
Exemple #2
0
        private static void SetReferenceItem(ConfigurableDictionaryNode configNode)
        {
            switch (configNode.FieldDescription)
            {
            case "Subentries":
                configNode.ReferenceItem = "MainEntrySubentries";
                if (configNode.DictionaryNodeOptions == null)
                {
                    configNode.DictionaryNodeOptions = new DictionaryNodeListAndParaOptions
                    {
                        ListId = DictionaryNodeListOptions.ListIds.Complex
                    };
                }
                break;

            case "SensesOS":
                if (configNode.Parent.FieldDescription == "SensesOS")                         // update only subsenses
                {
                    configNode.ReferenceItem = "MainEntrySubsenses";
                }
                break;

            case "SubentriesOS":                     // uniquely identifies Reversal Index Subentries
                configNode.ReferenceItem = "AllReversalSubentries";
                break;
            }
        }
 /// <summary>
 /// This recursive method will create group nodes in the migrated config and move all children in the node
 /// which belong in the group into it
 /// </summary>
 private static void MoveNodesIntoNewGroups(ConfigurableDictionaryNode oldConfigNode, ConfigurableDictionaryNode defaultNode)
 {
     if (oldConfigNode.Children == null || defaultNode.Children == null)
     {
         return;
     }
     // First recurse into each matching child node
     foreach (var oldChild in oldConfigNode.Children)
     {
         var matchFromDefault = FindMatchingChildNode(oldChild.Label, defaultNode.Children);
         if (matchFromDefault != null)
         {
             MoveNodesIntoNewGroups(oldChild, matchFromDefault);
         }
     }
     // Next find any groups at this level and move the matching children defaultChildren into the group
     foreach (var group in defaultNode.Children.Where(n => n.DictionaryNodeOptions is DictionaryNodeGroupingOptions))
     {
         // DeepClone skips children for grouping nodes. We want this, because we are going to move children in from the old configNode.
         var groupNode = group.DeepCloneUnderParent(oldConfigNode);
         groupNode.Children = new List <ConfigurableDictionaryNode>();
         for (var i = oldConfigNode.Children.Count - 1; i >= 0; --i)
         {
             var oldChild = oldConfigNode.Children[i];
             if (group.Children.Any(groupChild => groupChild.Label == oldChild.Label))
             {
                 groupNode.Children.Insert(0, oldChild);
                 oldChild.Parent = groupNode;
                 oldConfigNode.Children.RemoveAt(i);
             }
         }
         InsertNewNodeIntoOldConfig(oldConfigNode, groupNode, defaultNode, defaultNode.Children.IndexOf(group));
     }
 }
Exemple #4
0
        public void BuildPathStringFromNode()
        {
            var subsenses = new ConfigurableDictionaryNode {
                Label = "Subsenses", FieldDescription = "SensesOS", ReferenceItem = "SharedSenses"
            };
            var sharedSenses = new ConfigurableDictionaryNode
            {
                Label = "SharedSenses", FieldDescription = "SensesOS", Children = new List <ConfigurableDictionaryNode> {
                    subsenses
                }
            };
            var senses = new ConfigurableDictionaryNode {
                Label = "Senses", FieldDescription = "SensesOS", ReferenceItem = "SharedSenses"
            };
            var mainEntry = new ConfigurableDictionaryNode
            {
                FieldDescription = "LexEntry", Children = new List <ConfigurableDictionaryNode> {
                    senses
                }
            };
            var model = DictionaryConfigurationModelTests.CreateSimpleSharingModel(mainEntry, sharedSenses);

            CssGeneratorTests.PopulateFieldsForTesting(model);             // PopulateFieldsForTesting populates each node's Label with its FieldDescription

            Assert.AreEqual("LexEntry > Senses > SharedSenses > Subsenses", DictionaryConfigurationMigrator.BuildPathStringFromNode(subsenses));
            Assert.AreEqual("LexEntry > Senses > Subsenses", DictionaryConfigurationMigrator.BuildPathStringFromNode(subsenses, false));
            Assert.AreEqual("LexEntry", DictionaryConfigurationMigrator.BuildPathStringFromNode(mainEntry));
        }
Exemple #5
0
        /// <summary>
        /// Makes sure EntryType node contains ReverseAbbr and ReverseName nodes
        /// </summary>
        private static void SetEntryTypeChildrenBackward(ConfigurableDictionaryNode entryTypeNode)
        {
            var abbrNode = entryTypeNode.Children.Find(node => node.FieldDescription == Abbr);

            SwapOutNodeLabelAndField(abbrNode, ReversePrefix + Abbr, RevAbbr);
            var nameNode = entryTypeNode.Children.Find(node => node.FieldDescription == Name);

            SwapOutNodeLabelAndField(nameNode, ReversePrefix + Name, RevName);
        }
Exemple #6
0
        /// <summary>
        /// Makes sure EntryType node contains Abbreviation and Name nodes
        /// </summary>
        private static void SetEntryTypeChildrenForward(ConfigurableDictionaryNode entryTypeNode)
        {
            var abbrNode = entryTypeNode.Children.Find(node => node.FieldDescription == RevAbbr);

            SwapOutNodeLabelAndField(abbrNode, Abbr, Abbr);
            var nameNode = entryTypeNode.Children.Find(node => node.FieldDescription == RevName);

            SwapOutNodeLabelAndField(nameNode, Name, Name);
        }
Exemple #7
0
 private static void AddSubsubEntriesOptionsIfNeeded(ConfigurableDictionaryNode mainEntrySubEntries)
 {
     if (mainEntrySubEntries.DictionaryNodeOptions == null)
     {
         mainEntrySubEntries.DictionaryNodeOptions = new DictionaryNodeListAndParaOptions
         {
             ListId = DictionaryNodeListOptions.ListIds.Complex
         };
     }
 }
 /// <summary>LT-18288: Change Headword to HeadwordRef for All "Referenced Sense Headword" to allow users to select WS</summary>
 private static void ChangeReferenceSenseHeadwordFieldName(ConfigurableDictionaryNode oldConfigPart)
 {
     DCM.PerformActionOnNodes(oldConfigPart.Children, node =>
     {
         if (node.Label == "Referenced Sense Headword")
         {
             node.FieldDescription = "HeadWordRef";
         }
     });
 }
Exemple #9
0
        /// <summary>
        /// If node is a Pictures node, update its child nodes by removing Sense Number and adding Headword and Gloss.
        /// Part of LT-12572.
        /// </summary>
        private static void UpdatePicturesChildren(ConfigurableDictionaryNode node)
        {
            if (node == null)
            {
                return;
            }
            if (node.Label != "Pictures")
            {
                return;
            }

            node.Children.RemoveAll(child => child.Label == "Sense Number");

            var analysisWsOptions = new DictionaryNodeWritingSystemOptions
            {
                WsType = DictionaryNodeWritingSystemOptions.WritingSystemType.Analysis,
                DisplayWritingSystemAbbreviations = false,
                Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                {
                    new DictionaryNodeListOptions.DictionaryNodeOption {
                        Id = "analysis", IsEnabled = true
                    }
                }
            };

            var vernacularWsOptions = new DictionaryNodeWritingSystemOptions
            {
                WsType = DictionaryNodeWritingSystemOptions.WritingSystemType.Vernacular,
                DisplayWritingSystemAbbreviations = false,
                Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                {
                    new DictionaryNodeListOptions.DictionaryNodeOption {
                        Id = "vernacular", IsEnabled = true
                    }
                }
            };

            var headwordNode = new ConfigurableDictionaryNode
            {
                After     = "  ", Between = " ", Label = "Headword", FieldDescription = "Owner",
                SubField  = "OwnerOutlineName", CSSClassNameOverride = "headword",
                Style     = "Dictionary-Headword",
                IsEnabled = true, DictionaryNodeOptions = vernacularWsOptions
            };

            var glossNode = new ConfigurableDictionaryNode
            {
                After     = " ", Between = " ", Label = "Gloss", FieldDescription = "Owner",
                SubField  = "Gloss",
                IsEnabled = true, DictionaryNodeOptions = analysisWsOptions
            };

            node.Children.Add(headwordNode);
            node.Children.Add(glossNode);
        }
 /// <summary>LT-18286: One Sharing Parent in Hybrid erroneously got direct children (from a migration step). Remove them.</summary>
 private static void RemoveHiddenChildren(ConfigurableDictionaryNode parent, ISimpleLogger logger)
 {
     DCM.PerformActionOnNodes(parent.Children, p =>
     {
         if (p.ReferencedNode != null && p.Children != null && p.Children.Any())
         {
             logger.WriteLine(DCM.BuildPathStringFromNode(p) + " contains both Referenced And Direct Children. Removing Direct Children.");
             p.Children = new List <ConfigurableDictionaryNode>();
         }
     });
 }
 private static void RemoveReferencedHeadwordSubField(ConfigurableDictionaryNode part)
 {
     DCM.PerformActionOnNodes(part.Children, node =>
     {
         // AllReversalSubentries under Referenced Headword field is ReversalName
         if (node.FieldDescription == "ReversalName" && node.SubField == "MLHeadWord")
         {
             node.SubField = null;
         }
     });
 }
 private static void RemoveMostOfGramInfoUnderRefdComplexForms(ConfigurableDictionaryNode part)
 {
     DCM.PerformActionOnNodes(part.Children, node =>
     {
         // GramInfo under (Other) Ref'd Complex Forms is MorphoSystaxAnalyses
         // GramInfo under Senses  is MorphoSyntaxAnalysisRA and should not lose any children
         if (node.FieldDescription == "MorphoSyntaxAnalyses")
         {
             node.Children.RemoveAll(child => child.FieldDescription != "MLPartOfSpeech");
         }
     });
 }
Exemple #13
0
 /// <summary>LT-18920: Change Referringsenses to Senses for all the reversal index configurations.</summary>
 private static void ChangeReferringsensesToSenses(ConfigurableDictionaryNode part)
 {
     if (part.FieldDescription == "ReversalIndexEntry" || part.FieldDescription == "SubentriesOS")
     {
         DCM.PerformActionOnNodes(part.Children, node =>
         {
             if (node.FieldDescription == "ReferringSenses")
             {
                 node.FieldDescription = "SensesRS";
             }
         });
     }
 }
        private static void MigratePartFromOldVersionToCurrent(ISimpleLogger logger, DictionaryConfigurationModel oldConfig,
                                                               ConfigurableDictionaryNode oldConfigPart, ConfigurableDictionaryNode currentDefaultConfigPart)
        {
            var oldVersion = oldConfig.Version;

            if (oldVersion < FirstAlphaMigrator.VersionAlpha3)
            {
                throw new ApplicationException("Beta migration starts at VersionAlpha3 (8)");
            }
            switch (oldVersion)
            {
            case FirstAlphaMigrator.VersionAlpha3:
                MoveNodesIntoNewGroups(oldConfigPart, currentDefaultConfigPart);
                MigrateNewChildNodesAndOptionsInto(oldConfigPart, currentDefaultConfigPart);
                goto case 9;

            case 9:
                UpgradeEtymologyCluster(oldConfigPart, oldConfig);
                goto case 10;

            case 10:
            case 11:
            case 12:
            case 13:
                RemoveMostOfGramInfoUnderRefdComplexForms(oldConfigPart);
                goto case VersionBeta5;

            case VersionBeta5:
            case 15:
                MigrateNewChildNodesAndOptionsInto(oldConfigPart, currentDefaultConfigPart);
                goto case 16;

            case 16:
                RemoveHiddenChildren(oldConfigPart, logger);
                goto case VersionRC2;

            case VersionRC2:
                ChangeReferenceSenseHeadwordFieldName(oldConfigPart);
                goto case 18;

            case 18:
                RemoveReferencedHeadwordSubField(oldConfigPart);
                break;

            default:
                logger.WriteLine(string.Format(
                                     "Unable to migrate {0}: no migration instructions for version {1}", oldConfigPart.Label, oldVersion));
                break;
            }
        }
Exemple #15
0
 /// <summary>
 /// Swap out node Label and FieldDescription, checks for null node and empty strings
 /// in case only one of the parameters needs changing.
 /// </summary>
 private static void SwapOutNodeLabelAndField(ConfigurableDictionaryNode node, string label, string fieldDescription)
 {
     if (node == null)
     {
         return;
     }
     if (!string.IsNullOrEmpty(label))
     {
         node.Label = label;
     }
     if (!string.IsNullOrEmpty(fieldDescription))
     {
         node.FieldDescription = fieldDescription;
     }
 }
 private static void InsertNewNodeIntoOldConfig(ConfigurableDictionaryNode destinationParentNode, ConfigurableDictionaryNode newChildNode,
                                                ConfigurableDictionaryNode sourceParentNode, int indexInSourceParentNode)
 {
     if (indexInSourceParentNode == 0)
     {
         destinationParentNode.Children.Insert(0, newChildNode);
     }
     else
     {
         var olderSiblingLabel   = sourceParentNode.Children[indexInSourceParentNode - 1].Label;
         var indexOfOlderSibling = destinationParentNode.Children.FindIndex(n => n.Label == olderSiblingLabel);
         if (indexOfOlderSibling >= 0)
         {
             destinationParentNode.Children.Insert(indexOfOlderSibling + 1, newChildNode);
         }
         else
         {
             destinationParentNode.Children.Add(newChildNode);
         }
     }
 }
Exemple #17
0
 private static void UseConfigReferencedEntriesAsPrimary(ConfigurableDictionaryNode part)
 {
     if (part.FieldDescription == "ReversalIndexEntry" || part.FieldDescription == "SubentriesOS")
     {
         DCM.PerformActionOnNodes(part.Children, node =>
         {
             if (node.DisplayLabel == "Primary Entry References" && node.FieldDescription == "EntryRefsWithThisMainSense")
             {
                 node.FieldDescription = "MainEntryRefs";
                 node.HideCustomFields = true;
                 node.Before           = "  (";
                 node.After            = ")";
             }
             if (node.DisplayLabel == "Primary Entry(s)" && node.FieldDescription == "PrimarySensesOrEntries")
             {
                 node.FieldDescription     = "ConfigReferencedEntries";
                 node.CSSClassNameOverride = "referencedentries";
             }
         });
     }
 }
Exemple #18
0
        private static void AddSubsubNodeIfNeeded(ConfigurableDictionaryNode subNode)
        {
            if (subNode.Children.Any(n => n.FieldDescription == subNode.FieldDescription))
            {
                return;
            }
            switch (subNode.FieldDescription)
            {
            case "SensesOS":
                // On the odd chance Subsense has no SenseOptions, construct some.
                subNode.DictionaryNodeOptions = subNode.DictionaryNodeOptions ?? new DictionaryNodeSenseOptions();
                // Add in the new subsubsenses node
                subNode.Children.Add(new ConfigurableDictionaryNode
                {
                    Label                 = "Subsubsenses",
                    IsEnabled             = true,
                    Style                 = "Dictionary-Sense",
                    FieldDescription      = "SensesOS",
                    CSSClassNameOverride  = "subsenses",
                    ReferenceItem         = "MainEntrySubsenses",
                    DictionaryNodeOptions = subNode.DictionaryNodeOptions.DeepClone()
                });
                break;

            case "SubentriesOS":                     // SubentriesOS uniquely identifies Reversal Index subentries
                // Add in the new reversal subsubentries node
                subNode.Children.Add(new ConfigurableDictionaryNode
                {
                    Label                = "Reversal Subsubentries",
                    IsEnabled            = true,
                    Style                = "Reversal-Subentry",
                    FieldDescription     = "SubentriesOS",
                    CSSClassNameOverride = "subentries",
                    ReferenceItem        = "AllReversalSubentries"
                });
                break;
            }
        }
 private static void EnsureCssOverrideAndStylesAreUpdated(ConfigurableDictionaryNode destinationNode, ConfigurableDictionaryNode sourceNode)
 {
     if (sourceNode.StyleType != ConfigurableDictionaryNode.StyleTypes.Default && destinationNode.StyleType == ConfigurableDictionaryNode.StyleTypes.Default)
     {
         var nodeStyleType = sourceNode.StyleType;
         var nodeParaOpts  = destinationNode.DictionaryNodeOptions as IParaOption;
         if (nodeParaOpts != null)
         {
             nodeStyleType = nodeParaOpts.DisplayEachInAParagraph
                                         ? ConfigurableDictionaryNode.StyleTypes.Paragraph
                                         : ConfigurableDictionaryNode.StyleTypes.Character;
         }
         destinationNode.StyleType = nodeStyleType;
     }
     if (sourceNode.StyleType == destinationNode.StyleType &&             // in case the user changed, for example, from Paragraph to Character style
         !string.IsNullOrEmpty(sourceNode.Style) && string.IsNullOrEmpty(destinationNode.Style))
     {
         destinationNode.Style = sourceNode.Style;
     }
     if (!string.IsNullOrEmpty(sourceNode.CSSClassNameOverride) && string.IsNullOrEmpty(destinationNode.CSSClassNameOverride))
     {
         destinationNode.CSSClassNameOverride = sourceNode.CSSClassNameOverride;
     }
 }
        private static bool IsComplexFormsNode(ConfigurableDictionaryNode node)
        {
            var options = node.DictionaryNodeOptions as DictionaryNodeListOptions;

            return(options != null && options.ListId == DictionaryNodeListOptions.ListIds.Complex);
        }
        /// <summary>
        /// Case FirstAlphaMigrator.VersionAlpha3 above will pull in all the new nodes in the Etymology cluster by Label.
        /// Gloss is the only pre-existing node that doesn't have a new name, so it won't be replaced.
        /// It needs to be marked Enabled. The main Etymology node needs several modifications.
        /// Three old nodes will need deleting: Etymological Form, Comment and Source
        /// </summary>
        /// <param name="oldConfigPart"></param>
        /// <param name="oldConfig"></param>
        private static void UpgradeEtymologyCluster(ConfigurableDictionaryNode oldConfigPart, DictionaryConfigurationModel oldConfig)
        {
            if (oldConfigPart.Children == null || oldConfigPart.Children.Count == 0)
            {
                return;                 // safety net
            }
            var etymNodes = new List <ConfigurableDictionaryNode>();

            DCM.PerformActionOnNodes(oldConfigPart.Children, node =>
            {
                if (node.Label == "Etymology")
                {
                    etymNodes.Add(node);                     // since we have to do some node deleting, just collect up the relevant nodes
                }
            });

            foreach (var node in etymNodes)
            {
                if (node.IsCustomField)           // Unfortunately there are some pathological users who have ancient custom fields named etymology
                {
                    continue;                     // Leave them be
                }
                // modify main node
                var etymSequence = "EtymologyOS";
                if (oldConfig.IsReversal)
                {
                    node.SubField         = etymSequence;
                    node.FieldDescription = "Entry";
                    node.IsEnabled        = true;
                }
                else
                {
                    node.FieldDescription = etymSequence;
                    node.IsEnabled        = !oldConfig.IsHybrid;
                }
                node.CSSClassNameOverride = "etymologies";
                node.Before  = "(";
                node.Between = " ";
                node.After   = ") ";

                if (node.Children == null)
                {
                    continue;
                }

                // enable Gloss node
                var glossNode = node.Children.Find(n => n.Label == "Gloss");
                if (glossNode != null)
                {
                    glossNode.IsEnabled = true;
                }

                // enable Source Language Notes
                var notesList = node.Children.Find(n => n.FieldDescription == "LanguageNotes");
                if (notesList != null)                // ran into some cases where this node didn't exist in reversal config!
                {
                    notesList.IsEnabled = true;
                }

                // remove old children
                var nodesToRemove = new[] { "Etymological Form", "Comment", "Source" };
                node.Children.RemoveAll(n => nodesToRemove.Contains(n.Label));
            }
            // Etymology changed too much to be matched in the PreHistoricMigration and was marked as custom
            DCM.PerformActionOnNodes(etymNodes, n => { n.IsCustomField = false; });
        }
Exemple #22
0
        public void StoredDefaultsUpdatedFromCurrentDefaults()
        {
            var subsenses = new ConfigurableDictionaryNode {
                Label = "Subsenses", FieldDescription = "SensesOS"
            };
            var inBoth = new ConfigurableDictionaryNode
            {
                Label            = "In Both",
                FieldDescription = "Both"
            };
            var inOld = new ConfigurableDictionaryNode
            {
                Label            = "inOld",
                FieldDescription = "OnlyOld",
                Children         = new List <ConfigurableDictionaryNode> {
                    subsenses
                }
            };
            var senses = new ConfigurableDictionaryNode {
                Label = "Senses", FieldDescription = "SensesOS", Children = new List <ConfigurableDictionaryNode> {
                    inOld, inBoth
                }
            };
            var mainEntry = new ConfigurableDictionaryNode
            {
                FieldDescription = "LexEntry",
                Children         = new List <ConfigurableDictionaryNode> {
                    senses
                }
            };
            var oldModel = new DictionaryConfigurationModel {
                Parts = new List <ConfigurableDictionaryNode> {
                    mainEntry
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(oldModel);             // PopulateFieldsForTesting populates each node's Label with its FieldDescription sets all isEnabled to true
            var newMain = mainEntry.DeepCloneUnderSameParent();

            newMain.Children[0].Before    = "{";
            newMain.Children[0].Between   = ",";
            newMain.Children[0].After     = "}";
            newMain.Children[0].Style     = "Stylish";
            newMain.Children[0].IsEnabled = false;
            newMain.Children[0].Children.RemoveAt(0);             // Remove inOld
            var newModel = new DictionaryConfigurationModel {
                Parts = new List <ConfigurableDictionaryNode> {
                    newMain
                }
            };

            // Verify valid starting point
            Assert.AreNotEqual("{", oldModel.Parts[0].Children[0].Before, "Invalid preconditions");
            Assert.AreNotEqual("}", oldModel.Parts[0].Children[0].After, "Invalid preconditions");
            Assert.AreNotEqual(",", oldModel.Parts[0].Children[0].Between, "Invalid preconditions");
            Assert.AreNotEqual("Stylish", oldModel.Parts[0].Children[0].Style, "Invalid preconditions");
            Assert.True(oldModel.Parts[0].Children[0].IsEnabled, "Invalid preconditions");

            DictionaryConfigurationMigrator.LoadConfigWithCurrentDefaults(oldModel, newModel);             // SUT
            Assert.AreEqual(2, oldModel.Parts[0].Children[0].Children.Count, "Old non-matching part was not retained");
            Assert.AreEqual("{", oldModel.Parts[0].Children[0].Before, "Before not copied from new defaults");
            Assert.AreEqual("}", oldModel.Parts[0].Children[0].After, "After not copied from new defaults");
            Assert.AreEqual(",", oldModel.Parts[0].Children[0].Between, "Between not copied from new defaults");
            Assert.AreEqual("Stylish", oldModel.Parts[0].Children[0].Style, "Style not copied from new defaults");
            Assert.False(oldModel.Parts[0].Children[0].IsEnabled, "IsEnabled value not copied from new defaults");
        }