Example #1
0
        private void NestFile(string srcFwdataPathname)
        {
            var mdc            = GetFreshMdc();  // Want it fresh.
            var unownedObjects = new Dictionary <string, SortedDictionary <string, byte[]> >(200);
            // Outer dictionary has the class name for its key and a sorted (by guid) dictionary as its value.
            // The inner dictionary has a caseless guid as the key and the byte array as the value.
            var classData          = new Dictionary <string, SortedDictionary <string, byte[]> >(200, StringComparer.OrdinalIgnoreCase);
            var guidToClassMapping = new Dictionary <string, string>();

            TokenizeFile(mdc, srcFwdataPathname, unownedObjects, classData, guidToClassMapping);

            var root = new XElement("root");

            foreach (var unownedElementKvp in unownedObjects)
            {
                var className          = unownedElementKvp.Key;
                var classElement       = new XElement(className);
                var unownedElementDict = unownedElementKvp.Value;
                foreach (var unownedElement in unownedElementDict.Values)
                {
                    var element = Utilities.CreateFromBytes(unownedElement);
                    classElement.Add(element);
                    CmObjectNestingService.NestObject(false, element,
                                                      classData,
                                                      guidToClassMapping);
                }
                root.Add(classElement);
            }
            FileWriterService.WriteNestedFile(srcFwdataPathname + ".nested", root);
        }
Example #2
0
        internal static void NestStylesPropertyElement(
            IDictionary <string, SortedDictionary <string, byte[]> > classData,
            Dictionary <string, string> guidToClassMapping,
            XElement stylesProperty,
            string outputPathname)
        {
            if (stylesProperty == null)
            {
                return;
            }
            var styleObjSurElements = stylesProperty.Elements().ToList();

            if (!styleObjSurElements.Any())
            {
                return;
            }

            // Use only one file for all of them.
            var root = new XElement(SharedConstants.Styles);

            foreach (var styleObjSurElement in styleObjSurElements)
            {
                var styleGuid = styleObjSurElement.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant();
                var className = guidToClassMapping[styleGuid];
                var style     = Utilities.CreateFromBytes(classData[className][styleGuid]);
                CmObjectNestingService.NestObject(false, style, classData, guidToClassMapping);
                root.Add(style);
            }

            FileWriterService.WriteNestedFile(outputPathname, root);

            stylesProperty.RemoveNodes();
        }
        internal static void NestContext(string generalBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            // Write out each user-defined list (unowned CmPossibilityList) in a separate file.
            var userDefinedLists = classData[SharedConstants.CmPossibilityList].Values.Where(listElement => XmlUtils.GetAttributes(listElement, new HashSet <string> {
                SharedConstants.OwnerGuid
            })[SharedConstants.OwnerGuid] == null).ToList();

            if (!userDefinedLists.Any())
            {
                return;                 // Nothing to do.
            }
            var userDefinedDir = Path.Combine(generalBaseDir, "UserDefinedLists");

            if (!Directory.Exists(userDefinedDir))
            {
                Directory.CreateDirectory(userDefinedDir);
            }

            foreach (var userDefinedListBytes in userDefinedLists)
            {
                var element = Utilities.CreateFromBytes(userDefinedListBytes);
                CmObjectNestingService.NestObject(
                    false,
                    element,
                    classData,
                    guidToClassMapping);
                FileWriterService.WriteNestedFile(
                    Path.Combine(userDefinedDir, "UserList-" + element.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant() + "." + SharedConstants.List),
                    new XElement("UserDefinedList", element));
            }
        }
Example #4
0
        /// <summary>
        /// Some of the code is from: https://www.stevejgordon.co.uk/running-net-core-generic-host-applications-as-a-windows-service
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static async Task Main(string[] args)
        {
            var isService = !(Debugger.IsAttached || args.Contains("--console"));

            if (isService)
            {
                var pathToExe         = Process.GetCurrentProcess().MainModule.FileName;
                var pathToContentRoot = Path.GetDirectoryName(pathToExe);
                Directory.SetCurrentDirectory(pathToContentRoot);
            }

            var builder = CreateWebHostBuilder(
                args.Where(arg => arg != "--console").ToArray());

            var host = builder.Build();

            if (isService)
            {
                host.RunAsFileWriterWebHostService();
            }
            else
            {
                var storeViewHubService = new FileWriterService();
                await storeViewHubService.StartAsync();

                host.Run();
                Console.WriteLine("Service Started");
            }
        }
        private static void NestLists(IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                      Dictionary <string, string> guidToClassMapping,
                                      IDictionary <string, byte[]> posLists,
                                      string lexiconRootDir,
                                      XContainer owningElement,
                                      IEnumerable <string> propNames)
        {
            foreach (var propName in propNames)
            {
                var listPropElement = owningElement.Element(propName);
                if (listPropElement == null || !listPropElement.HasElements)
                {
                    continue;
                }

                var root        = new XElement(propName);
                var listElement = Utilities.CreateFromBytes(posLists[listPropElement.Elements().First().Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant()]);
                CmObjectNestingService.NestObject(false,
                                                  listElement,
                                                  classData,
                                                  guidToClassMapping);
                listPropElement.RemoveNodes();                 // Remove the single list objsur element.
                root.Add(listElement);

                FileWriterService.WriteNestedFile(Path.Combine(lexiconRootDir, propName + "." + SharedConstants.List), root);
            }
        }
Example #6
0
        internal static void NestContext(XElement langProj,
                                         string scriptureBaseDir,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            if (!Directory.Exists(scriptureBaseDir))
            {
                return;
            }

            var clPropElement = langProj.Element(CheckLists);

            if (clPropElement == null || !clPropElement.HasElements)
            {
                return;
            }

            foreach (var checkListObjSurElement in clPropElement.Elements())
            {
                var checkListGuid = checkListObjSurElement.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant();
                var className     = guidToClassMapping[checkListGuid];
                var checkList     = Utilities.CreateFromBytes(classData[className][checkListGuid]);

                CmObjectNestingService.NestObject(false, checkList,
                                                  classData,
                                                  guidToClassMapping);

                FileWriterService.WriteNestedFile(Path.Combine(scriptureBaseDir, checkList.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant() + "." + SharedConstants.List), new XElement("CheckList", checkList));
            }

            clPropElement.RemoveNodes();
        }
        internal static void NestContext(XElement archivedDraftsProperty,
                                         string scriptureBaseDir,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            if (archivedDraftsProperty == null)
            {
                return;
            }
            var drafts = archivedDraftsProperty.Elements().ToList();

            if (!drafts.Any())
            {
                return;
            }

            foreach (var draftObjSur in drafts)
            {
                var root      = new XElement(SharedConstants.ArchivedDrafts);
                var draftGuid = draftObjSur.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant();
                var className = guidToClassMapping[draftGuid];
                var draft     = Utilities.CreateFromBytes(classData[className][draftGuid]);

                CmObjectNestingService.NestObject(false, draft,
                                                  classData,
                                                  guidToClassMapping);

                root.Add(draft);
                FileWriterService.WriteNestedFile(Path.Combine(scriptureBaseDir, SharedConstants.Draft + "_" + draftGuid.ToLowerInvariant() + "." + SharedConstants.ArchivedDraft), root);
            }

            archivedDraftsProperty.RemoveNodes();
        }
Example #8
0
        internal static void NestContext(XElement importSettingsProperty,
                                         string scriptureBaseDir,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            if (importSettingsProperty == null)
            {
                return;
            }
            var importSettings = importSettingsProperty.Elements().ToList();

            if (!importSettings.Any())
            {
                return;
            }

            var root = new XElement(SharedConstants.ImportSettings);

            foreach (var importSettingObjSur in importSettings)
            {
                var styleGuid     = importSettingObjSur.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant();
                var className     = guidToClassMapping[styleGuid];
                var importSetting = Utilities.CreateFromBytes(classData[className][styleGuid]);

                CmObjectNestingService.NestObject(false, importSetting,
                                                  classData,
                                                  guidToClassMapping);

                root.Add(importSetting);
            }

            FileWriterService.WriteNestedFile(Path.Combine(scriptureBaseDir, SharedConstants.ImportSettingsFilename), root);

            importSettingsProperty.RemoveNodes();
        }
Example #9
0
        internal static void RemoveBoundedContextDataCore(string contextBaseDir)
        {
            if (!Directory.Exists(contextBaseDir))
            {
                return;
            }

            foreach (var pathname in Directory.GetFiles(contextBaseDir, "*.*", SearchOption.AllDirectories)
                     .Where(pathname => Path.GetExtension(pathname).ToLowerInvariant() != ".chorusnotes"))
            {
                File.Delete(pathname);
            }

            FileWriterService.RemoveEmptyFolders(contextBaseDir, true);
        }
Example #10
0
        public IChangePresenter GetChangePresenter(IChangeReport report, HgRepository repository)
        {
            if (report == null)
            {
                throw new ArgumentNullException("report");
            }
            if (repository == null)
            {
                throw new ArgumentNullException("repository");
            }

            var extension = FileWriterService.GetExtensionFromPathname(report.PathToFile);

            return(GetHandlerfromExtension(extension).GetChangePresenter(report, repository));
        }
Example #11
0
 private void GenerateButton_Click(object sender, EventArgs e)
 {
     try
     {
         UseWaitCursor = true;
         string        replacementLiteral = GetReplacementLiteral();
         string        hardpointCode      = GetHardpointCode();
         int           hardpointCount     = GetHardpointCountToCreate();
         List <string> hardpointTable;
         if (IsTurretCheckBox.Checked)
         {
             hardpointTable = CreateTurretHpList(hardpointCode, replacementLiteral, hardpointCount,
                                                 GetHardPointBaseName());
         }
         else
         {
             hardpointTable =
                 HardPointGeneratorService.GenerateHpVariants(hardpointCode, replacementLiteral, hardpointCount);
         }
         FileWriterService.WriteToFile(hardpointTable);
         UseWaitCursor = false;
         MessageBox.Show(Strings.SuccessfullyCreadedMessage, Strings.Success, MessageBoxButtons.OK,
                         MessageBoxIcon.Information);
     }
     catch (MissingReplacementPatternException missingReplacementPatternException)
     {
         UseWaitCursor = false;
         MessageBox.Show(missingReplacementPatternException.ToString(), Strings.Error,
                         MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
     catch (MissingHardpointCodeException missingHardpointCodeException)
     {
         UseWaitCursor = false;
         MessageBox.Show(missingHardpointCodeException.ToString(), Strings.Error,
                         MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
     catch (MissingHardpointBaseNameException missingHardpointBaseNameException)
     {
         UseWaitCursor = false;
         MessageBox.Show(missingHardpointBaseNameException.ToString(), Strings.Error,
                         MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
     catch (Exception ex)
     {
         UseWaitCursor = false;
         MessageBox.Show(ex.ToString(), Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
Example #12
0
        /// <summary>
        /// All callers merging FieldWorks data need to pass 'true', so the MDC will know about  any custom properties for their classes.
        ///
        /// Non-object callers (currently only the merge of the custom property definitions themselves) shoudl pass 'false'.
        /// </summary>
        internal static void Do3WayMerge(MergeOrder mergeOrder, MetadataCache mdc, bool addcustomPropertyInformation)
        {
            // Skip doing this for the Custom property definiton file, since it has no real need for the custom prop definitions,
            // which are being merged (when 'false' is provided).
            if (addcustomPropertyInformation)
            {
                mdc.AddCustomPropInfo(mergeOrder);                 // NB: Must be done before FieldWorksCommonMergeStrategy is created. since it used the MDC.
            }
            var merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, mdc);

            merger.EventListener = mergeOrder.EventListener;
            var mergeResults = merger.MergeFiles(mergeOrder.pathToOurs, mergeOrder.pathToTheirs, mergeOrder.pathToCommonAncestor);

            // Write out merged data.
            FileWriterService.WriteNestedFile(mergeOrder.pathToOurs, mergeResults.MergedNode);
        }
        internal static void NestContext(string linguisticsBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var phonologyDir = Path.Combine(linguisticsBaseDir, SharedConstants.Phonology);

            if (!Directory.Exists(phonologyDir))
            {
                Directory.CreateDirectory(phonologyDir);
            }

            var langProjElement = wellUsedElements[SharedConstants.LangProject];

            // 1. Nest: LP's PhonologicalData(PhPhonData OA) (Also does PhPhonData's PhonRuleFeats(CmPossibilityList)
            // NB: PhPhonData is a singleton
            var phonDataPropElement = langProjElement.Element("PhonologicalData");
            var phonDataElement     = Utilities.CreateFromBytes(classData["PhPhonData"].Values.First());

            // 1.A. Write: Break out PhPhonData's PhonRuleFeats(CmPossibilityList OA) and write in its own .list file. (If it exists, but *before* nesting "PhPhonData".)
            FileWriterService.WriteNestedListFileIfItExists(
                classData, guidToClassMapping,
                phonDataElement, "PhonRuleFeats",
                Path.Combine(phonologyDir, SharedConstants.PhonRuleFeaturesFilename));
            phonDataPropElement.RemoveNodes();
            CmObjectNestingService.NestObject(
                false,
                phonDataElement,
                classData,
                guidToClassMapping);
            // 2. Nest: LP's PhFeatureSystem(FsFeatureSystem OA)
            var phonFeatureSystemPropElement = langProjElement.Element("PhFeatureSystem");
            var phonFeatureSystemElement     = Utilities.CreateFromBytes(classData["FsFeatureSystem"][phonFeatureSystemPropElement.Element(SharedConstants.Objsur).Attribute(SharedConstants.GuidStr).Value]);

            phonFeatureSystemPropElement.RemoveNodes();
            CmObjectNestingService.NestObject(
                false,
                phonFeatureSystemElement,
                classData,
                guidToClassMapping);
            // B. Write: LP's PhonologicalData(PhPhonData) (Sans its PhonRuleFeats(CmPossibilityList) in a new extension (phondata).
            FileWriterService.WriteNestedFile(Path.Combine(phonologyDir, SharedConstants.PhonologicalDataFilename), new XElement("PhonologicalData", phonDataElement));
            // C. Write: LP's PhFeatureSystem(FsFeatureSystem) in its own file with a new (shared extension of featsys).
            FileWriterService.WriteNestedFile(Path.Combine(phonologyDir, SharedConstants.PhonologyFeaturesFilename), new XElement(SharedConstants.FeatureSystem, phonFeatureSystemElement));
        }
Example #14
0
        public IEnumerable <IChangeReport> Find2WayDifferences(FileInRevision parent, FileInRevision child, HgRepository repository)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");                 // Parent seems not be optional in Chorus usage.
            }
            if (child == null)
            {
                throw new ArgumentNullException("child");
            }
            if (repository == null)
            {
                throw new ArgumentNullException("repository");
            }

            var extension = FileWriterService.GetExtensionFromPathname(child.FullPath);

            return(GetHandlerfromExtension(extension).Find2WayDifferences(parent, child, repository));
        }
Example #15
0
        public void Do3WayMerge(MergeOrder mergeOrder)
        {
            if (mergeOrder == null)
            {
                throw new ArgumentNullException("mergeOrder");
            }

            // Make sure MDC is updated.
            // Since this method is called in another process by ChorusMerge,
            // the MDC that was set up for splitting the file is not available.
            var extension = FileWriterService.GetExtensionFromPathname(mergeOrder.pathToOurs);

            if (extension != SharedConstants.ModelVersion)
            {
                var pathToOurs = mergeOrder.pathToOurs;
                var folder     = Path.GetDirectoryName(pathToOurs);
                while (!File.Exists(Path.Combine(folder, SharedConstants.ModelVersionFilename)))
                {
                    var parent = Directory.GetParent(folder);
                    folder = parent != null?parent.ToString() : null;

                    if (folder == null)
                    {
                        break;
                    }
                }
                // 'folder' should now have the required model version file in it, or null for some tests.
                var desiredModelNumber = MetadataCache.MaximumModelVersion;
                if (folder != null)
                {
                    var ourModelFileData = File.ReadAllText(Path.Combine(folder, SharedConstants.ModelVersionFilename));
                    desiredModelNumber = Int32.Parse(ModelVersionFileTypeHandlerStrategy.SplitData(ourModelFileData)[1]);
                }
                MetadataCache.MdCache.UpgradeToVersion(desiredModelNumber);
            }

            XmlMergeService.RemoveAmbiguousChildNodes = false;             // Live on the edge. Opt out of that expensive code.

            GetHandlerfromExtension(extension).Do3WayMerge(MetadataCache.MdCache, mergeOrder);
        }
Example #16
0
        private MetadataCache GetFreshMdc()
        {
            var mdc = MetadataCache.TestOnlyNewCache;
            var modelVersionPathname = Path.Combine(_workingDir, SharedConstants.ModelVersionFilename);

            if (!File.Exists(modelVersionPathname))
            {
                FLExProjectSplitter.WriteVersionFile(_srcFwdataPathname);
                using (var fastSplitter = new FastXmlElementSplitter(_srcFwdataPathname))
                {
                    bool foundOptionalFirstElement;
                    // NB: The main input file *does* have to deal with the optional first element.
                    foreach (var record in fastSplitter.GetSecondLevelElementBytes(SharedConstants.AdditionalFieldsTag, SharedConstants.RtTag, out foundOptionalFirstElement))
                    {
                        if (foundOptionalFirstElement)
                        {
                            // 2. Write custom properties file with custom properties.
                            FileWriterService.WriteCustomPropertyFile(mdc, _workingDir, record);
                        }
                        else
                        {
                            // Write empty custom properties file.
                            FileWriterService.WriteCustomPropertyFile(Path.Combine(_workingDir, SharedConstants.CustomPropertiesFilename), null);
                        }
                        break;
                    }
                }
            }
            var modelData = File.ReadAllText(modelVersionPathname);

            mdc.UpgradeToVersion(Int32.Parse(modelData.Split(new[] { "{", ":", "}" }, StringSplitOptions.RemoveEmptyEntries)[1]));
            var customPropPathname = Path.Combine(_workingDir, SharedConstants.CustomPropertiesFilename);

            mdc.AddCustomPropInfo(new MergeOrder(
                                      customPropPathname, customPropPathname, customPropPathname,
                                      new MergeSituation(customPropPathname, "", "", "", "", MergeOrder.ConflictHandlingModeChoices.WeWin)));
            return(mdc);
        }
        public void CustomFileHasKeyAttributeForEachCustomProperty()
        {
            const string originalCustomData =
                @"<AdditionalFields>
	<CustomField class='LexEntry' destclass='7' listRoot='53241fd4-72ae-4082-af55-6b659657083c' name='Tone' type='RC' />
	<CustomField class='LexSense' name='Paradigm' type='String' wsSelector='-2' />
	<CustomField class='WfiWordform' name='Certified' type='Boolean' />
</AdditionalFields>";

            var tempPathname = Path.Combine(Path.GetTempPath(), SharedConstants.CustomPropertiesFilename);

            FileWriterService.WriteCustomPropertyFile(MetadataCache.TestOnlyNewCache, Path.GetTempPath(), SharedConstants.Utf8.GetBytes(originalCustomData));
            using (var tempFile = TempFile.TrackExisting(tempPathname))
            {
                var doc = XDocument.Load(tempFile.Path);
                Assert.IsTrue(doc.Root.Name.LocalName == "AdditionalFields");
                Assert.AreEqual(3, doc.Root.Elements().Count());
                foreach (var customPropertyDeclaration in doc.Root.Elements())
                {
                    Assert.IsNotNull(customPropertyDeclaration.Attribute("key"));
                }
            }
        }
Example #18
0
        internal static void NestContext(string baseDirectory,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var sortedInstanceData = classData["ScrRefSystem"];

            if (sortedInstanceData.Count == 0)
            {
                return;
            }
            if (!Directory.Exists(baseDirectory))
            {
                Directory.CreateDirectory(baseDirectory);
            }

            var refSystem = Utilities.CreateFromBytes(sortedInstanceData.First().Value);

            CmObjectNestingService.NestObject(false, refSystem,
                                              classData,
                                              guidToClassMapping);

            FileWriterService.WriteNestedFile(Path.Combine(baseDirectory, SharedConstants.ScriptureReferenceSystemFilename), new XElement(SharedConstants.ScriptureReferenceSystem, refSystem));
        }
Example #19
0
        internal static void NestContext(string generalBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var langProjElement = wellUsedElements[SharedConstants.LangProject];

            // LP AnnotationDefs (OA-CmPossibilityList). AnnotationDefs.list]
            FileWriterService.WriteNestedListFileIfItExists(classData,
                                                            guidToClassMapping,
                                                            langProjElement, SharedConstants.AnnotationDefs,
                                                            Path.Combine(generalBaseDir, SharedConstants.AnnotationDefsListFilename));

            // LP Styles (OC-StStyle) is used by everyone, but Scripture, so they go here.
            BaseDomainServices.NestStylesPropertyElement(
                classData,
                guidToClassMapping,
                langProjElement.Element(SharedConstants.Styles),
                Path.Combine(generalBaseDir, SharedConstants.FLExStylesFilename));

            // LP Filters (OC) can go into one filters file here. (FLExFilters.filter: new ext)
            var owningPropElement = langProjElement.Element(SharedConstants.Filters);

            if (owningPropElement != null && owningPropElement.HasElements)
            {
                var root = new XElement(SharedConstants.Filters);
                foreach (var filterObjSurElement in owningPropElement.Elements().ToList())
                {
                    var filterGuid    = filterObjSurElement.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant();
                    var className     = guidToClassMapping[filterGuid];
                    var filterElement = Utilities.CreateFromBytes(classData[className][filterGuid]);
                    CmObjectNestingService.NestObject(false, filterElement, classData, guidToClassMapping);
                    root.Add(filterElement);
                }
                FileWriterService.WriteNestedFile(Path.Combine(generalBaseDir, SharedConstants.FLExFiltersFilename), root);
                owningPropElement.RemoveNodes();
            }

            // LP Annotations (OC). Who still uses them? If all else fails, or they are used by several BCs, then store them in one file here.
            // [FLExAnnotations.annotation: new ext]
            // OJO! Sig is "CmAnnotation", which is abtract class, so handle like in Discourse-land.
            owningPropElement = langProjElement.Element(SharedConstants.Annotations);
            if (owningPropElement != null && owningPropElement.HasElements)
            {
                var root = new XElement(SharedConstants.Annotations);
                foreach (var annotationObjSurElement in owningPropElement.Elements().ToList())
                {
                    var annotationGuid    = annotationObjSurElement.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant();
                    var className         = guidToClassMapping[annotationGuid];
                    var annotationElement = Utilities.CreateFromBytes(classData[className][annotationGuid]);
                    CmObjectNestingService.NestObject(false, annotationElement, classData, guidToClassMapping);
                    BaseDomainServices.ReplaceElementNameWithAndAddClassAttribute(SharedConstants.CmAnnotation, annotationElement);
                    root.Add(annotationElement);
                }
                FileWriterService.WriteNestedFile(Path.Combine(generalBaseDir, SharedConstants.FLExAnnotationsFilename), root);
                owningPropElement.RemoveNodes();
            }

            // Some CmPicture instances may not be owned.
            var rootElement     = new XElement(SharedConstants.Pictures);
            var unownedPictures = classData[SharedConstants.CmPicture].Values.Where(listElement => XmlUtils.GetAttributes(listElement, new HashSet <string> {
                SharedConstants.OwnerGuid
            })[SharedConstants.OwnerGuid] == null).ToList();

            foreach (var unownedPictureBytes in unownedPictures)
            {
                var element = Utilities.CreateFromBytes(unownedPictureBytes);
                CmObjectNestingService.NestObject(
                    false,
                    element,
                    classData,
                    guidToClassMapping);
                rootElement.Add(element);
            }
            FileWriterService.WriteNestedFile(Path.Combine(generalBaseDir, SharedConstants.FLExUnownedPicturesFilename), rootElement);

            // No VirtualOrdering instances are owned.
            if (MetadataCache.MdCache.ModelVersion > MetadataCache.StartingModelVersion)
            {
                rootElement = new XElement(SharedConstants.VirtualOrderings);
                foreach (var element in classData[SharedConstants.VirtualOrdering].Values.ToArray().Select(virtualOrderingBytes => Utilities.CreateFromBytes(virtualOrderingBytes)))
                {
                    CmObjectNestingService.NestObject(
                        false,
                        element,
                        classData,
                        guidToClassMapping);
                    rootElement.Add(element);
                }
                FileWriterService.WriteNestedFile(Path.Combine(generalBaseDir, SharedConstants.FLExVirtualOrderingFilename), rootElement);
            }

            // Yippee!! Write LP here. :-) [LanguageProject.langproj; new ext]
            CmObjectNestingService.NestObject(false,
                                              langProjElement,
                                              classData,
                                              guidToClassMapping);
            FileWriterService.WriteNestedFile(Path.Combine(generalBaseDir, SharedConstants.LanguageProjectFilename), new XElement(SharedConstants.LanguageProject, langProjElement));
        }
        internal static void NestContext(string anthropologyDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var sortedInstanceData = classData["RnResearchNbk"];
            var langProj           = wellUsedElements[SharedConstants.LangProject];
            var headerElement      = new XElement(SharedConstants.Header);
            var rootElement        = new XElement(SharedConstants.Anthropology, headerElement);

            if (sortedInstanceData.Count > 0)
            {
                // 1. Main RnResearchNbk element.
                var notebookElement = Utilities.CreateFromBytes(sortedInstanceData.Values.First());
                headerElement.Add(notebookElement);

                CmObjectNestingService.NestObject(false, notebookElement,
                                                  classData,
                                                  guidToClassMapping);

                // Pull out the RecTypes OA pos list prop from RnResearchNbk and write as its own list file.
                // It is nested by now, if it exists at all.
                var recTypesOwningPropElement = notebookElement.Element("RecTypes");
                if (recTypesOwningPropElement != null && recTypesOwningPropElement.HasElements)
                {
                    FileWriterService.WriteNestedFile(
                        Path.Combine(anthropologyDir, "RecTypes." + SharedConstants.List),
                        new XElement("RecTypes", recTypesOwningPropElement.Element(SharedConstants.CmPossibilityList)));
                    recTypesOwningPropElement.RemoveNodes();
                }

                var recordsElement = notebookElement.Element("Records");
                if (recordsElement != null && recordsElement.HasElements)
                {
                    // Put nested (by this time) records all in as children of root.
                    rootElement.Add(recordsElement.Elements());       // NB: These were already sorted, way up in MultipleFileServices::CacheDataRecord, since "Records" is a collection prop.
                    recordsElement.RemoveNodes();                     // Leaves empty Records element placeholder in RnResearchNbk element.
                }
                // Remove child objsur nodes from owning LangProg
                langProj.Element("ResearchNotebook").RemoveNodes();
            }

            FileWriterService.WriteNestedFile(Path.Combine(anthropologyDir, SharedConstants.DataNotebookFilename), rootElement);

            // LangProj props to write. (List props will remain in lang proj, but the list obsur will be removed.)
            // Write each of several lists into individual files.

            /* Anthro-related lists owned by LangProj.
             *              case "AnthroList":
             *              case "ConfidenceLevels":
             *              case "Education":
             *              case "Locations":
             *              case "People":
             *              case "Positions":
             *              case "Restrictions":
             *              case "Roles":
             *              case "Status":
             *              case "TimeOfDay":
             */
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "AnthroList",
                                                            Path.Combine(anthropologyDir, "AnthroList." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "ConfidenceLevels",
                                                            Path.Combine(anthropologyDir, "ConfidenceLevels." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "Education",
                                                            Path.Combine(anthropologyDir, "Education." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "Locations",
                                                            Path.Combine(anthropologyDir, "Locations." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "People",
                                                            Path.Combine(anthropologyDir, "People." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "Positions",
                                                            Path.Combine(anthropologyDir, "Positions." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "Restrictions",
                                                            Path.Combine(anthropologyDir, "Restrictions." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "Roles",
                                                            Path.Combine(anthropologyDir, "Roles." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "Status",
                                                            Path.Combine(anthropologyDir, "Status." + SharedConstants.List));
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProj, "TimeOfDay",
                                                            Path.Combine(anthropologyDir, "TimeOfDay." + SharedConstants.List));
        }
        internal static void NestContext(XElement languageProjectElement,
                                         XElement scriptureElement,
                                         string baseDirectory,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            // baseDirectory is root/Scripture and has already been created by caller.
            var scriptureBaseDir = baseDirectory;

            // Split out the optional NoteCategories list.
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            scriptureElement, SharedConstants.NoteCategories,
                                                            Path.Combine(scriptureBaseDir, SharedConstants.NoteCategoriesListFilename));

            // Extract all 66 required 'ScrBookAnnotations' instances from BookAnnotations property, and write to corresponding subfolder.
            // Leave property, but emptied of <objsur elements>.
            var booksDir = Path.Combine(scriptureBaseDir, SharedConstants.Books);

            if (!Directory.Exists(booksDir))
            {
                Directory.CreateDirectory(booksDir);
            }
            var allAnnotations           = classData[SharedConstants.ScrBookAnnotations];
            var annotationObjSurElements = scriptureElement.Element(SharedConstants.BookAnnotations).Elements().ToList();

            scriptureElement.Element(SharedConstants.BookAnnotations).RemoveNodes();
            for (var canonicalBookNumber = 1; canonicalBookNumber < 67; ++canonicalBookNumber)
            {
                var paddedNumber             = ScriptureDomainServices.PaddedCanonicalBookNumer(canonicalBookNumber);
                var currentAnnotationElement = Utilities.CreateFromBytes(allAnnotations[annotationObjSurElements[canonicalBookNumber - 1].Attribute(SharedConstants.GuidStr).Value]);
                CmObjectNestingService.NestObject(false, currentAnnotationElement,
                                                  classData,
                                                  guidToClassMapping);
                FileWriterService.WriteNestedFile(
                    Path.Combine(booksDir, paddedNumber + "." + SharedConstants.bookannotations),
                    new XElement(SharedConstants.BookAnnotations, currentAnnotationElement));
            }

            // Extract any optional ScrBook instances from 'ScriptureBooks', and write each to corresponding subfolder.
            var allBooks = classData[SharedConstants.ScrBook];
            var scriptureBooksProperty = scriptureElement.Element(SharedConstants.ScriptureBooks);

            if (scriptureBooksProperty != null && scriptureBooksProperty.HasElements)
            {
                List <XElement> bookObjSurElements = scriptureElement.Element(SharedConstants.ScriptureBooks).Elements().ToList();
                scriptureElement.Element(SharedConstants.ScriptureBooks).RemoveNodes();
                foreach (var objsurEl in bookObjSurElements)
                {
                    var currentBookElement = Utilities.CreateFromBytes(allBooks[objsurEl.Attribute(SharedConstants.GuidStr).Value]);
                    var paddedNumber       = ScriptureDomainServices.PaddedCanonicalBookNumer(Int32.Parse(currentBookElement.Element("CanonicalNum").Attribute("val").Value));
                    CmObjectNestingService.NestObject(false, currentBookElement,
                                                      classData,
                                                      guidToClassMapping);
                    FileWriterService.WriteNestedFile(
                        Path.Combine(booksDir, paddedNumber + "." + SharedConstants.book),
                        new XElement(SharedConstants.Book, currentBookElement));
                }
            }

            CmObjectNestingService.NestObject(false, scriptureElement,
                                              classData,
                                              guidToClassMapping);

            FileWriterService.WriteNestedFile(
                Path.Combine(scriptureBaseDir, SharedConstants.ScriptureTransFilename),
                new XElement(SharedConstants.TranslatedScripture, scriptureElement));

            languageProjectElement.Element(SharedConstants.TranslatedScripture).RemoveNodes();
        }
Example #22
0
 public MirrorVoiceCommandService()
 {
     settingsService = new FileWriterService();
 }
        internal static void NestContext(string linguisticsBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var sortedPunctuationFormInstanceData = classData["PunctuationForm"];
            var sortedWfiWordformInstanceData     = classData["WfiWordform"];

            var inventoryDir = Path.Combine(linguisticsBaseDir, SharedConstants.WordformInventoryRootFolder);

            if (!Directory.Exists(inventoryDir))
            {
                Directory.CreateDirectory(inventoryDir);
            }

            // the doc root will be "Inventory" (SharedConstants.WordformInventoryRootFolder).
            // This will store the PunctuationForm instances (unowned) in the header, and each PunctuationForm will be a child of header.
            // Each WfiWordform (unowned) will then be a child of root.
            var header = new XElement(SharedConstants.Header);
            // Work on copy, since 'classData' is changed during the loop.
            SortedDictionary <string, byte[]> srcDataCopy;

            if (sortedPunctuationFormInstanceData.Count > 0)
            {
                // There may be no punct forms, even if there are wordforms, so header really is optional.
                srcDataCopy = new SortedDictionary <string, byte[]>(sortedPunctuationFormInstanceData);
                foreach (var punctFormStringData in srcDataCopy.Values)
                {
                    var pfElement = Utilities.CreateFromBytes(punctFormStringData);
                    header.Add(pfElement);
                    CmObjectNestingService.NestObject(false,
                                                      pfElement,
                                                      classData,
                                                      guidToClassMapping);
                }
            }

            var nestedData = new SortedDictionary <string, XElement>();

            if (sortedWfiWordformInstanceData.Count > 0)
            {
                // Work on copy, since 'classData' is changed during the loop.
                srcDataCopy = new SortedDictionary <string, byte[]>(sortedWfiWordformInstanceData);
                foreach (var wordFormElement in srcDataCopy.Values)
                {
                    var wfElement        = Utilities.CreateFromBytes(wordFormElement);
                    var checksumProperty = wfElement.Element("Checksum");
                    if (checksumProperty != null)
                    {
                        // Can be null, for DMs less than 64.
                        checksumProperty.Attribute(SharedConstants.Val).Value = "0";
                    }
                    CmObjectNestingService.NestObject(false,
                                                      wfElement,
                                                      classData,
                                                      guidToClassMapping);
                    nestedData.Add(wfElement.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant(), wfElement);
                }
            }

            var buckets = FileWriterService.CreateEmptyBuckets(10);

            FileWriterService.FillBuckets(buckets, nestedData);

            for (var i = 0; i < buckets.Count; ++i)
            {
                var root = new XElement(SharedConstants.WordformInventoryRootFolder);
                if (i == 0 && header.HasElements)
                {
                    root.Add(header);
                }
                var currentBucket = buckets[i];
                foreach (var wordform in currentBucket.Values)
                {
                    root.Add(wordform);
                }
                FileWriterService.WriteNestedFile(PathnameForBucket(inventoryDir, i), root);
            }
        }
        /// <summary>
        /// Start doing whatever is needed for the supported type of action.
        /// </summary>
        /// <returns>'true' if the caller expects the main window to be shown, otherwise 'false'.</returns>
        public void StartWorking(Dictionary <string, string> commandLineArgs)
        {
            // -p <$fwroot>\foo\foo.fwdata
            var projectDir = Path.GetDirectoryName(commandLineArgs["-p"]);

            using (var chorusSystem = Utilities.InitializeChorusSystem(projectDir, commandLineArgs["-u"], FlexFolderSystem.ConfigureChorusProjectFolder))
            {
                var newlyCreated = false;
                if (chorusSystem.Repository.Identifier == null)
                {
                    // Write an empty custom prop file to get something in the default branch at rev 0.
                    // The custom prop file will always exist and can be empty, so start it as empty (null).
                    // This basic rev 0 commit will then allow for a roll back if the soon to follow main commit fails on a validation problem.
                    FileWriterService.WriteCustomPropertyFile(Path.Combine(projectDir, SharedConstants.CustomPropertiesFilename), null);
                    chorusSystem.Repository.AddAndCheckinFile(Path.Combine(projectDir, SharedConstants.CustomPropertiesFilename));
                    newlyCreated = true;
                }
                chorusSystem.EnsureAllNotesRepositoriesLoaded();

                // Add the 'lock' file to keep FW apps from starting up at such an inopportune moment.
                var projectName  = Path.GetFileNameWithoutExtension(commandLineArgs["-p"]);
                var lockPathname = Path.Combine(projectDir, projectName + SharedConstants.FwXmlLockExtension);
                try
                {
                    File.WriteAllText(lockPathname, "");
                    var origPathname = Path.Combine(projectDir, projectName + Utilities.FwXmlExtension);

                    // Do the Chorus business.
                    using (var syncDlg = (SyncDialog)chorusSystem.WinForms.CreateSynchronizationDialog(SyncUIDialogBehaviors.Lazy, SyncUIFeatures.NormalRecommended | SyncUIFeatures.PlaySoundIfSuccessful))
                    {
                        // The FlexBridgeSynchronizerAdjunct class (implements ISychronizerAdjunct) handles the fwdata file splitting and restoring
                        // now.  'syncDlg' sees to it that the Synchronizer class ends up with FlexBridgeSynchronizerAdjunct, and the Synchronizer
                        // class then calls one of the methods of the ISychronizerAdjunct interface right before the first Commit (local commit)
                        // call.  If two heads are merged, then the Synchoronizer class calls the second method of the ISychronizerAdjunct
                        // interface, (once for each pair of merged heads) so Flex Bridge can restore the fwdata file, AND, most importantly,
                        // produce any needed incompatible move conflict reports of the merge, which are then included in the post-merge commit.
                        var syncAdjunt = new FlexBridgeSynchronizerAdjunct(origPathname, commandLineArgs["-f"], false);
                        syncDlg.SetSynchronizerAdjunct(syncAdjunt);

                        // Chorus does it in this order:
                        // Local Commit
                        // Pull
                        // Merge (Only if anything came in with the pull from other sources, and commit of merged results)
                        // Push
                        syncDlg.SyncOptions.DoPullFromOthers  = true;
                        syncDlg.SyncOptions.DoMergeWithOthers = true;
                        syncDlg.SyncOptions.DoSendToOthers    = true;
                        syncDlg.Text          = Resources.SendReceiveView_DialogTitleFlexProject;
                        syncDlg.StartPosition = FormStartPosition.CenterScreen;
                        syncDlg.BringToFront();
                        var dlgResult = syncDlg.ShowDialog();

                        if (dlgResult == DialogResult.OK)
                        {
                            if (newlyCreated && (!syncDlg.SyncResult.Succeeded || syncDlg.SyncResult.ErrorEncountered != null))
                            {
                                _gotChanges = false;
                                // Wipe out new repo, since something bad happened in S/R,
                                // and we don't want to leave the user in a sad state (cf. LT-14751, LT-14957).
                                BackOutOfRepoCreation(projectDir);
                            }
                            else if (syncDlg.SyncResult.DidGetChangesFromOthers || syncAdjunt.WasUpdated)
                            {
                                _gotChanges = true;
                            }
                        }
                        else
                        {
                            // User probably bailed out of S/R using the "X" to close the dlg.
                            if (newlyCreated)
                            {
                                _gotChanges = false;
                                // Wipe out new repo, since the user cancelled without even trying the S/R,
                                // and we don't want to leave the user in a sad state (cf. LT-14751, LT-14957).
                                BackOutOfRepoCreation(projectDir);
                            }
                        }
                    }
                }
                finally
                {
                    if (File.Exists(lockPathname))
                    {
                        File.Delete(lockPathname);
                    }
                }
            }
        }
        internal static void NestContext(string linguisticsBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var lexiconDir = Path.Combine(linguisticsBaseDir, SharedConstants.Lexicon);

            if (!Directory.Exists(lexiconDir))
            {
                Directory.CreateDirectory(lexiconDir);
            }

            var lexDb = wellUsedElements[SharedConstants.LexDb];             // It has had its "ReversalIndexes" property processed already, so it should be an empty element.
            // lexDb is owned by the LP in its LexDb property, so remove its <objsur> node.
            var langProjElement = wellUsedElements[SharedConstants.LangProject];

            langProjElement.Element(SharedConstants.LexDb).RemoveNodes();

            // Nest each CmPossibilityList owned by LexDb.
            var lists = classData[SharedConstants.CmPossibilityList];

            NestLists(classData, guidToClassMapping, lists, lexiconDir, lexDb,
                      new List <string>
            {
                "SenseTypes",
                "UsageTypes",
                "DomainTypes",
                // Moved to Morph & Syn, as per AndyB. "MorphTypes",
                "References",
                "VariantEntryTypes",
                "ComplexEntryTypes",
                "Languages",
                "DialectLabels",
                "ExtendedNoteTypes",
                "PublicationTypes"
            });

            // Nest SemanticDomainList and AffixCategories props of LangProject.
            NestLists(classData, guidToClassMapping, lists, lexiconDir, langProjElement,
                      new List <string>
            {
                "SemanticDomainList",
                "AffixCategories"
            });

            // The LexDb object will go into the <header>, and will still nest these owning props: Appendixes, Introduction, and Resources (plus its basic props).
            // All of the lexical entries will then go in as siblings of, but after, the <header> element.
            // At this point LexDb is ready to go into the <header>.
            CmObjectNestingService.NestObject(false, lexDb,
                                              classData,
                                              guidToClassMapping);
            var header = new XElement(SharedConstants.Header);

            header.Add(lexDb);

            var sortedEntryInstanceData = classData[SharedConstants.LexEntry];
            var nestedData = new SortedDictionary <string, XElement>();

            if (sortedEntryInstanceData.Count > 0)
            {
                var srcDataCopy = new SortedDictionary <string, byte[]>(sortedEntryInstanceData);
                foreach (var entry in srcDataCopy.Values)
                {
                    var entryElement = Utilities.CreateFromBytes(entry);
                    CmObjectNestingService.NestObject(false, entryElement,
                                                      classData,
                                                      guidToClassMapping);
                    nestedData.Add(entryElement.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant(), entryElement);
                }
            }

            var buckets = FileWriterService.CreateEmptyBuckets(10);

            FileWriterService.FillBuckets(buckets, nestedData);

            for (var i = 0; i < buckets.Count; ++i)
            {
                var root = new XElement(SharedConstants.Lexicon);
                if (i == 0 && header.HasElements)
                {
                    root.Add(header);
                }
                var currentBucket = buckets[i];
                foreach (var entry in currentBucket.Values)
                {
                    root.Add(entry);
                }
                FileWriterService.WriteNestedFile(PathnameForBucket(lexiconDir, i), root);
            }
        }
        internal static void NestContext(string linguisticsBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var lexDb = wellUsedElements[SharedConstants.LexDb];

            if (lexDb == null)
            {
                return;                 // No LexDb, then there can be no reversals.
            }
            SortedDictionary <string, byte[]> sortedInstanceData = classData["ReversalIndex"];

            if (sortedInstanceData.Count == 0)
            {
                return;                                     // no reversals, as in Lela-Teli-3.
            }
            lexDb.Element("ReversalIndexes").RemoveNodes(); // Restored in FlattenContext method.

            var reversalDir = Path.Combine(linguisticsBaseDir, ReversalRootFolder);

            if (!Directory.Exists(reversalDir))
            {
                Directory.CreateDirectory(reversalDir);
            }

            var srcDataCopy = new SortedDictionary <string, byte[]>(sortedInstanceData);

            foreach (var reversalIndexKvp in srcDataCopy)
            {
                var revIndexElement = Utilities.CreateFromBytes(reversalIndexKvp.Value);
                var ws          = revIndexElement.Element("WritingSystem").Element("Uni").Value;
                var revIndexDir = Path.Combine(reversalDir, ws);
                if (!Directory.Exists(revIndexDir))
                {
                    Directory.CreateDirectory(revIndexDir);
                }

                var reversalFilename = ws + ".reversal";

                // Break out ReversalIndex's PartsOfSpeech(CmPossibilityList OA) and write in its own .list file.
                FileWriterService.WriteNestedListFileIfItExists(
                    classData, guidToClassMapping,
                    revIndexElement, SharedConstants.PartsOfSpeech,
                    Path.Combine(revIndexDir, ws + "-" + SharedConstants.PartsOfSpeechFilename));

                CmObjectNestingService.NestObject(false, revIndexElement,
                                                  classData,
                                                  guidToClassMapping);

                var entriesElement = revIndexElement.Element("Entries");
                var root           = new XElement("Reversal",
                                                  new XElement(SharedConstants.Header, revIndexElement));
                if (entriesElement != null && entriesElement.Elements().Any())
                {
                    root.Add(entriesElement.Elements());
                    // NB: These were already sorted, way up in MultipleFileServices::CacheDataRecord, since "Entries" is a collection prop.
                    entriesElement.RemoveNodes();
                }

                FileWriterService.WriteNestedFile(Path.Combine(revIndexDir, reversalFilename), root);
            }
        }
Example #27
0
        internal static void NestContext(string linguisticsBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var textCorpusBaseDir = Path.Combine(linguisticsBaseDir, SharedConstants.TextCorpus);

            if (!Directory.Exists(textCorpusBaseDir))
            {
                Directory.CreateDirectory(textCorpusBaseDir);
            }

            var langProjElement = wellUsedElements[SharedConstants.LangProject];

            // Write Genre list (owning atomic CmPossibilityList)
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProjElement, SharedConstants.GenreList,
                                                            Path.Combine(textCorpusBaseDir, SharedConstants.GenreListFilename));

            // Write text markup tags list (owning atomic CmPossibilityList)
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProjElement, SharedConstants.TextMarkupTags,
                                                            Path.Combine(textCorpusBaseDir, SharedConstants.TextMarkupTagsListFilename));

            // Handle the LP TranslationTags prop (OA-CmPossibilityList), if it exists.
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProjElement, SharedConstants.TranslationTags,
                                                            Path.Combine(textCorpusBaseDir, SharedConstants.TranslationTagsListFilename));

            var texts = classData["Text"];

            if (texts.Count == 0)
            {
                return;                 // No texts to process.
            }
            if (MetadataCache.MdCache.ModelVersion < 7000059)
            {
                // Backwards compatible code.
                var textGuidsInLangProj = BaseDomainServices.GetGuids(langProjElement, "Texts");
                if (textGuidsInLangProj.Count == 0)
                {
                    return;                     //  None owned by lang project. (Some can be owned by RnGenericRec.)
                }
                foreach (var textGuid in textGuidsInLangProj)
                {
                    var rootElement = new XElement("TextInCorpus");
                    var textElement = Utilities.CreateFromBytes(texts[textGuid]);
                    rootElement.Add(textElement);
                    CmObjectNestingService.NestObject(
                        false,
                        textElement,
                        classData,
                        guidToClassMapping);
                    FileWriterService.WriteNestedFile(
                        Path.Combine(textCorpusBaseDir, "Text_" + textGuid.ToLowerInvariant() + "." + SharedConstants.TextInCorpus),
                        rootElement);
                }
                // Remove child objsur nodes from owning LangProg
                langProjElement.Element("Texts").RemoveNodes();
            }
            else
            {
                foreach (var textGuid in texts.Keys.ToArray())                 // Needs a copy, since the dictionary is changed.
                {
                    var rootElement = new XElement("TextInCorpus");
                    var textElement = Utilities.CreateFromBytes(texts[textGuid]);
                    rootElement.Add(textElement);
                    CmObjectNestingService.NestObject(
                        false,
                        textElement,
                        classData,
                        guidToClassMapping);
                    FileWriterService.WriteNestedFile(
                        Path.Combine(textCorpusBaseDir, "Text_" + textGuid.ToLowerInvariant() + "." + SharedConstants.TextInCorpus),
                        rootElement);
                }
            }
        }
        internal static void NestContext(string linguisticsBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var discourseDir = Path.Combine(linguisticsBaseDir, SharedConstants.DiscourseRootFolder);

            if (!Directory.Exists(discourseDir))
            {
                Directory.CreateDirectory(discourseDir);
            }

            var sortedInstanceData = classData["DsDiscourseData"];

            if (sortedInstanceData.Count == 0)
            {
                return;
            }

            // 'discourseElement' is owned by LangProj in DsDiscourseData prop (OA).
            var discourseElement = Utilities.CreateFromBytes(sortedInstanceData.Values.First());

            // Nest the entire object, and then pull out the owned stuff, and relocate them, as needed.
            CmObjectNestingService.NestObject(
                false,
                discourseElement,
                classData,
                guidToClassMapping);

            var listElement = discourseElement.Element(SharedConstants.ConstChartTempl);

            if (listElement != null)
            {
                // NB: Write list file, but only if discourseElement has the list.
                FileWriterService.WriteNestedFile(Path.Combine(discourseDir, SharedConstants.ConstChartTemplFilename), listElement);
                listElement.RemoveNodes();
            }

            listElement = discourseElement.Element(SharedConstants.ChartMarkers);
            if (listElement != null)
            {
                // NB: Write list file, but only if discourseElement has the list.
                FileWriterService.WriteNestedFile(Path.Combine(discourseDir, SharedConstants.ChartMarkersFilename), listElement);
                listElement.RemoveNodes();
            }

            // <owning num="2" id="Charts" card="col" sig="DsChart"> [Abstract. Owns nothing special, but is subclass of CmMajorObject.]
            //		Disposition: Write in main discourse file as the repeating series of objects, BUT use the abstract class for the repeating element, since Gordon sees new subclasses of it coming along.

            // NB: We will just let the normal nesting code work over discourseElement,
            // which will put in the actual subclass name as the element tag.
            // So, we'll just intercept them out of the owning prop elemtent (if any exist), and patch them up here.
            // NB: If there are no such charts, then do the usual of making one with the empty guid for its Id.
            var root   = new XElement(SharedConstants.DiscourseRootFolder);
            var header = new XElement(SharedConstants.Header);

            root.Add(header);
            header.Add(discourseElement);
            // Remove child objsur node from owning LangProg
            var langProjElement = wellUsedElements[SharedConstants.LangProject];

            langProjElement.Element("DiscourseData").RemoveNodes();

            var chartElements = discourseElement.Element("Charts");

            if (chartElements != null && chartElements.HasElements)
            {
                foreach (var chartElement in chartElements.Elements())
                {
                    BaseDomainServices.ReplaceElementNameWithAndAddClassAttribute(SharedConstants.DsChart, chartElement);
                    // It is already nested.
                    root.Add(chartElement);
                }
                chartElements.RemoveNodes();
            }

            FileWriterService.WriteNestedFile(Path.Combine(discourseDir, SharedConstants.DiscourseChartFilename), root);
        }
        internal static void NestContext(string linguisticsBaseDir,
                                         IDictionary <string, XElement> wellUsedElements,
                                         IDictionary <string, SortedDictionary <string, byte[]> > classData,
                                         Dictionary <string, string> guidToClassMapping)
        {
            var morphAndSynDir = Path.Combine(linguisticsBaseDir, SharedConstants.MorphologyAndSyntax);

            if (!Directory.Exists(morphAndSynDir))
            {
                Directory.CreateDirectory(morphAndSynDir);
            }

            var lexDb = wellUsedElements[SharedConstants.LexDb];

            if (lexDb != null)
            {
                // Write out LexDb's "MorphTypes" list, as per AndyB (7 Feb 2012).
                FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                                lexDb, SharedConstants.MorphTypes,
                                                                Path.Combine(morphAndSynDir, SharedConstants.MorphTypesListFilename));
            }
            var langProjElement = wellUsedElements[SharedConstants.LangProject];
            // 1. Nest: LP's MorphologicalData(MoMorphData OA) (Also does MoMorphData's ProdRestrict(CmPossibilityList)
            //		Remove objsur node from LP.
            var morphologicalDataPropElement = langProjElement.Element("MorphologicalData");

            morphologicalDataPropElement.RemoveNodes();
            var morphDataElement = Utilities.CreateFromBytes(classData["MoMorphData"].Values.First());

            CmObjectNestingService.NestObject(
                false,
                morphDataElement,
                classData,
                guidToClassMapping);
            // Hold off writing it until its list is written.

            // 2. Nest: LP's MsFeatureSystem(FsFeatureSystem OA)
            //		Remove objsur node from LP.
            var morphFeatureSystemPropElement = langProjElement.Element("MsFeatureSystem");
            var morphFeatureSystemElement     = Utilities.CreateFromBytes(classData["FsFeatureSystem"][morphFeatureSystemPropElement.Element(SharedConstants.Objsur).Attribute(SharedConstants.GuidStr).Value]);

            morphFeatureSystemPropElement.RemoveNodes();
            CmObjectNestingService.NestObject(
                false,
                morphFeatureSystemElement,
                classData,
                guidToClassMapping);
            FileWriterService.WriteNestedFile(Path.Combine(morphAndSynDir, SharedConstants.MorphAndSynFeaturesFilename), new XElement(SharedConstants.FeatureSystem, morphFeatureSystemElement));

            // 3. Nest: LP's PartsOfSpeech(CmPossibilityList OA)
            //		Remove objsur node from LP.
            FileWriterService.WriteNestedListFileIfItExists(classData, guidToClassMapping,
                                                            langProjElement, SharedConstants.PartsOfSpeech,
                                                            Path.Combine(morphAndSynDir, SharedConstants.PartsOfSpeechFilename));

            // 4. Nest: LP's AnalyzingAgents(CmAgent OC) (use some new extension and a fixed name)
            //		Remove objsur node(s) from LP.
            var agents      = classData["CmAgent"];
            var rootElement = new XElement(SharedConstants.AnalyzingAgents);

            foreach (var agentGuid in BaseDomainServices.GetGuids(langProjElement, SharedConstants.AnalyzingAgents))
            {
                var agentElement = Utilities.CreateFromBytes(agents[agentGuid]);
                rootElement.Add(agentElement);
                CmObjectNestingService.NestObject(
                    false,
                    agentElement,
                    classData,
                    guidToClassMapping);
            }
            FileWriterService.WriteNestedFile(Path.Combine(morphAndSynDir, SharedConstants.AnalyzingAgentsFilename), rootElement);
            langProjElement.Element(SharedConstants.AnalyzingAgents).RemoveNodes();

            // A. Write: MoMorphData's ProdRestrict(CmPossibilityList OA) and write in its own .list file.
            //		Remove ProdRestrict node child in MoMorphData
            var prodRestrictPropElement = morphDataElement.Element("ProdRestrict");

            if (prodRestrictPropElement != null && prodRestrictPropElement.HasElements)
            {
                // NB: Write file, but only if morphDataElement has the list.
                FileWriterService.WriteNestedFile(Path.Combine(morphAndSynDir, "ProdRestrict." + SharedConstants.List), prodRestrictPropElement);
                prodRestrictPropElement.RemoveNodes();
            }

            // B. Write: LP's MorphologicalData(MoMorphData OA) in a new extension (morphdata)
            FileWriterService.WriteNestedFile(Path.Combine(morphAndSynDir, SharedConstants.MorphAndSynDataFilename), new XElement(SharedConstants.MorphAndSynData, morphDataElement));
        }