Bloom.Book.Book.BringBookUpToDate C# (CSharp) Method

BringBookUpToDate() private method

As the bloom format evolves, including structure and classes and other attributes, this makes changes to old books. It needs to be very fast, because currently we dont' have a real way to detect the need for migration. So we do it all the time. Yes, we have format version number, but, for example, one overhaul of the common xmatter html introduced a new class, "frontCover". Hardly enough to justify bumping the version number and making older Blooms unable to read new books. But because this is run, the xmatter will be migrated to the new template.
private BringBookUpToDate ( HtmlDom bookDOM, IProgress progress ) : void
bookDOM HtmlDom
progress IProgress
return void
        private void BringBookUpToDate(HtmlDom bookDOM /* may be a 'preview' version*/, IProgress progress)
        {
            if (Title.Contains("allowSharedUpdate"))
            {
                // Original version of this code that suffers BL_3166
                progress.WriteStatus("Updating Front/Back Matter...");
                BringXmatterHtmlUpToDate(bookDOM);

                progress.WriteStatus("Gathering Data...");
                TranslationGroupManager.PrepareElementsInPageOrDocument(bookDOM.RawDom, _collectionSettings);
                progress.WriteStatus("Updating Data...");

                InjectStringListingActiveLanguagesOfBook();

                //hack
                if (bookDOM == OurHtmlDom) //we already have a data for this
                {
                    _bookData.SynchronizeDataItemsThroughoutDOM();

                    // I think we should only mess with tags if we are updating the book for real.
                    var oldTagsPath = Path.Combine(_storage.FolderPath, "tags.txt");
                    if (RobustFile.Exists(oldTagsPath))
                    {
                        ConvertTagsToMetaData(oldTagsPath, BookInfo);
                        RobustFile.Delete(oldTagsPath);
                    }
                }
                else //used for making a preview dom
                {
                    var bd = new BookData(bookDOM, _collectionSettings, UpdateImageMetadataAttributes);
                    bd.SynchronizeDataItemsThroughoutDOM();
                }
                // get any license info into the json and restored in the replaced front matter.
                BookCopyrightAndLicense.SetMetadata(GetLicenseMetadata(), bookDOM, FolderPath, CollectionSettings);

                bookDOM.RemoveMetaElement("bloomBookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val);
                bookDOM.RemoveMetaElement("bookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val);
                // BookInfo will always have an ID, the constructor makes one even if there is no json file.
                // To allow migration, pretend it has no ID if there is not yet a meta.json.
                bookDOM.RemoveMetaElement("bloomBookId", () => (RobustFile.Exists(BookInfo.MetaDataPath) ? BookInfo.Id : null),
                    val => BookInfo.Id = val);

                // Title should be replicated in json
                //if (!string.IsNullOrWhiteSpace(Title)) // check just in case we somehow have more useful info in json.
                //    bookDOM.Title = Title;
                // Bit of a kludge, but there's no way to tell whether a boolean is already set in the JSON, so we fake that it is not,
                // thus ensuring that if something is in the metadata we use it.
                // If there is nothing there the default of true will survive.
                bookDOM.RemoveMetaElement("SuitableForMakingVernacularBooks", () => null,
                    val => BookInfo.IsSuitableForVernacularLibrary = val == "yes" || val == "definitely");

                UpdateTextsNewlyChangedToRequiresParagraph(bookDOM);

                //we've removed and possible added pages, so our page cache is invalid
                _pagesCache = null;
            }
            else
            {
                // New version that we hope prevents BL_3166
                if (_doingBookUpdate)
                    MessageBox.Show("Caught Bloom doing two updates at once! Possible BL-3166 is being prevented");
                lock (_updateLock)
                {
                    _doingBookUpdate = true;
                    progress.WriteStatus("Updating Front/Back Matter...");
                    // Nothing in the update process should change the license info, so save what is current before we mess with
                    // anything (may fix BL-3166).
                    var licenseMetadata = GetLicenseMetadata();
                    BringXmatterHtmlUpToDate(bookDOM);

                    progress.WriteStatus("Gathering Data...");
                    TranslationGroupManager.PrepareElementsInPageOrDocument(bookDOM.RawDom, _collectionSettings);
                    progress.WriteStatus("Updating Data...");

                    InjectStringListingActiveLanguagesOfBook();

                    //hack
                    if (bookDOM == OurHtmlDom) //we already have a data for this
                    {
                        _bookData.SynchronizeDataItemsThroughoutDOM();

                        // I think we should only mess with tags if we are updating the book for real.
                        var oldTagsPath = Path.Combine(_storage.FolderPath, "tags.txt");
                        if (RobustFile.Exists(oldTagsPath))
                        {
                            ConvertTagsToMetaData(oldTagsPath, BookInfo);
                            RobustFile.Delete(oldTagsPath);
                        }
                    }
                    else //used for making a preview dom
                    {
                        var bd = new BookData(bookDOM, _collectionSettings, UpdateImageMetadataAttributes);
                        bd.SynchronizeDataItemsThroughoutDOM();
                    }
                    // get any license info into the json and restored in the replaced front matter.
                    BookCopyrightAndLicense.SetMetadata(licenseMetadata, bookDOM, FolderPath, CollectionSettings);

                    bookDOM.RemoveMetaElement("bloomBookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val);
                    bookDOM.RemoveMetaElement("bookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val);
                    // BookInfo will always have an ID, the constructor makes one even if there is no json file.
                    // To allow migration, pretend it has no ID if there is not yet a meta.json.
                    bookDOM.RemoveMetaElement("bloomBookId", () => (RobustFile.Exists(BookInfo.MetaDataPath) ? BookInfo.Id : null),
                        val => BookInfo.Id = val);

                    // Title should be replicated in json
                    //if (!string.IsNullOrWhiteSpace(Title)) // check just in case we somehow have more useful info in json.
                    //    bookDOM.Title = Title;
                    // Bit of a kludge, but there's no way to tell whether a boolean is already set in the JSON, so we fake that it is not,
                    // thus ensuring that if something is in the metadata we use it.
                    // If there is nothing there the default of true will survive.
                    bookDOM.RemoveMetaElement("SuitableForMakingVernacularBooks", () => null,
                        val => BookInfo.IsSuitableForVernacularLibrary = val == "yes" || val == "definitely");

                    UpdateTextsNewlyChangedToRequiresParagraph(bookDOM);

                    //we've removed and possible added pages, so our page cache is invalid
                    _pagesCache = null;
                    _doingBookUpdate = false;
                }
            }
        }

Same methods

Book::BringBookUpToDate ( IProgress progress ) : void

Usage Example

        public void BringBookUpToDate_MigratesReaderToolsAvailableToToolboxIsOpen()
        {
            var oldMetaData =
                "{\"bookInstanceId\":\"3328aa4a - 2ef3 - 43a8 - a656 - 1d7c6f00444c\",\"folio\":false,\"title\":\"Landscape basic book\",\"baseUrl\":null,\"bookOrder\":null,\"isbn\":\"\",\"bookLineage\":\"056B6F11-4A6C-4942-B2BC-8861E62B03B3\",\"downloadSource\":null,\"license\":\"cc-by\",\"formatVersion\":\"2.0\",\"licenseNotes\":null,\"copyright\":null,\"authors\":null,\"credits\":\"\",\"tags\":[\"<p>\r\n</p>\"],\"pageCount\":0,\"languages\":[],\"langPointers\":null,\"summary\":null,\"allowUploadingToBloomLibrary\":true,\"bookletMakingIsAppropriate\":true,\"uploader\":null,\"tools\":null,\"readerToolsAvailable\":true}";
            var storage = GetInitialStorage();

            // This seems to be needed to let it locate some kind of collection settings.
            var    folder  = storage.FolderPath;
            var    locator = (FileLocator)storage.GetFileLocator();
            string root    = FileLocator.GetDirectoryDistributedWithApplication(BloomFileLocator.BrowserRoot);

            locator.AddPath(root.CombineForPath("bookLayout"));
            var collectionSettings =
                new CollectionSettings(new NewCollectionSettings()
            {
                PathToSettingsFile  = CollectionSettings.GetPathForNewSettings(folder, "test"),
                Language1Iso639Code = "xyz",
                Language2Iso639Code = "en",
                Language3Iso639Code = "fr"
            });
            var book = new Bloom.Book.Book(new BookInfo(folder, true), storage, new Mock <ITemplateFinder>().Object,
                                           collectionSettings,
                                           new Mock <PageSelection>().Object, new PageListChangedEvent(), new BookRefreshEvent());
            var jsonPath = book.BookInfo.MetaDataPath;

            File.WriteAllText(jsonPath, oldMetaData);

            book.BringBookUpToDate(new NullProgress());

            Assert.That(book.BookInfo.ToolboxIsOpen, Is.True);
        }
All Usage Examples Of Bloom.Book.Book::BringBookUpToDate
Book