public void VerifyStringForBackupPropertiesLabel() { var restoreProjectPresenter = new RestoreProjectPresenter(null, string.Empty); BackupFileSettings backupSettings = new BackupFileSettings( Path.ChangeExtension("dummy", FdoFileHelper.ksFwBackupFileExtension), false); // This is needed to thwart BackupFileSettings's normal logic to populate the flags // from the backup zip file ReflectionHelper.SetField(backupSettings, "m_projectName", "dummy"); ReflectionHelper.SetField(backupSettings, "m_configurationSettings", true); String resultStr = restoreProjectPresenter.IncludesFiles(backupSettings); Assert.AreEqual("Configuration settings", resultStr); ReflectionHelper.SetField(backupSettings, "m_supportingFiles", true); resultStr = restoreProjectPresenter.IncludesFiles(backupSettings); Assert.AreEqual("Configuration settings and Supporting Files.", resultStr); ReflectionHelper.SetField(backupSettings, "m_configurationSettings", false); resultStr = restoreProjectPresenter.IncludesFiles(backupSettings); Assert.AreEqual("Supporting Files", resultStr); ReflectionHelper.SetField(backupSettings, "m_linkedFiles", true); resultStr = restoreProjectPresenter.IncludesFiles(backupSettings); Assert.AreEqual("Linked files and Supporting Files.", resultStr); ReflectionHelper.SetField(backupSettings, "m_configurationSettings", true); resultStr = restoreProjectPresenter.IncludesFiles(backupSettings); Assert.AreEqual("Configuration settings, Linked files and Supporting Files.", resultStr); ReflectionHelper.SetField(backupSettings, "m_spellCheckAdditions", true); resultStr = restoreProjectPresenter.IncludesFiles(backupSettings); Assert.AreEqual("Configuration settings, Linked files, Supporting Files and Spelling dictionary.", resultStr); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Perform a restore of the project specified in the settings. /// </summary> /// <param name="progressDlg">The progress dialog.</param> /// <exception cref="IOException">File does not exist, or some such problem</exception> /// <exception cref="InvalidBackupFileException">XML deserialization problem or required /// files not found in zip file</exception> /// ------------------------------------------------------------------------------------ public void RestoreProject(IThreadedProgress progressDlg) { BackupFileSettings fileSettings = m_restoreSettings.Backup; fileSettings.Validate(); // Normally, this will already have been done, so this will do nothing. bool suppressConversion = false; //First of all, if the project exists and we are overwriting it, then make a copy of the project. That way //if the restoration fails part way through, we can put it back the way it was. if (Directory.Exists(m_restoreSettings.ProjectPath)) { // If the project already exists using the fwdata extension, either we're not sharing, // or it is a project for which sharing is suppressed. In any case we don't want to // convert the new project. suppressConversion = File.Exists(m_restoreSettings.FullProjectPath); CreateACopyOfTheProject(); } //When restoring a project, ensure all the normal folders are there even if some //of those folders had nothing from them in the backup. Directory.CreateDirectory(m_restoreSettings.ProjectPath); FdoCache.CreateProjectSubfolders(m_restoreSettings.ProjectPath); try { //Import from FW version 6.0 based on the file extension. string extension = Path.GetExtension(fileSettings.File).ToLowerInvariant(); if (extension == FwFileExtensions.ksFw60BackupFileExtension || extension == ".xml") { ImportFrom6_0Backup(fileSettings, progressDlg); } else //Restore from FW version 7.0 and newer backup. { RestoreFrom7_0AndNewerBackup(fileSettings); } } catch (Exception error) { if (error is IOException || error is InvalidBackupFileException || error is UnauthorizedAccessException) { CleanupAfterRestore(false); // ENHANCE: If/when we have the restore process using a progress dialog so that this code // runs in the progress dialog thread instead of the main thread, all message boxes should // be replaced with the ThreadHelper.ShowMessageBox() method so that they will be thread-safe. MessageBoxUtils.Show(null, error.Message, AppStrings.ksRestoreDidNotSucceed, MessageBoxButtons.OK, MessageBoxIcon.Information); } throw; } // switch to the desired backend (if it's in the projects directory...anything else stays XML for now). if (DirectoryFinder.IsSubFolderOfProjectsDirectory(m_restoreSettings.ProjectPath) && !suppressConversion) { ClientServerServices.Current.Local.ConvertToDb4oBackendIfNeeded(progressDlg, m_restoreSettings.FullProjectPath); } CleanupAfterRestore(true); }
private void ImportFrom6_0Backup(BackupFileSettings fileSettings, IThreadedProgress progressDlg) { var importer = new ImportFrom6_0(progressDlg, m_converterConsolePath, m_dbPath); bool importSuccessful; try { string projFile; importSuccessful = importer.Import(fileSettings.File, m_restoreSettings.ProjectName, m_restoreSettings.ProjectsRootFolder, out projFile); } catch (CannotConvertException e) { FailedImportCleanUp(importer); throw; } if (!importSuccessful) { FailedImportCleanUp(importer); if (!importer.HaveOldFieldWorks || !importer.HaveFwSqlServer) { throw new MissingOldFwException("Error restoring from FieldWorks 6.0 (or earlier) backup", importer.HaveFwSqlServer, importer.HaveOldFieldWorks); } throw new FailedFwRestoreException("Error restoring from FieldWorks 6.0 (or earlier) backup"); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Return a string indicating which sets of files were included in the backup. /// This is internal for testing purposes. /// </summary> /// <param name="settings">The settings.</param> /// ------------------------------------------------------------------------------------ internal String IncludesFiles(BackupFileSettings settings) { List<string> itemsBackedUp = new List<string>(); if (settings.IncludeConfigurationSettings) itemsBackedUp.Add(FwCoreDlgs.ksConfigurationSettingsRestoreDlg); if (settings.IncludeLinkedFiles) itemsBackedUp.Add(FwCoreDlgs.ksMediaFilesRestoreDlg); if (settings.IncludeSupportingFiles) itemsBackedUp.Add(FwCoreDlgs.ksSupportingFilesRestoreDlg); if (settings.IncludeSpellCheckAdditions) itemsBackedUp.Add(FwCoreDlgs.ksSpellingFilesRestoreDlg); int numberOfFileSetsBackedUp = itemsBackedUp.Count; if (numberOfFileSetsBackedUp == 0) return string.Empty; StringBuilder strbldr = new StringBuilder(); strbldr.Append(itemsBackedUp[0]); for (int i = 1; i < numberOfFileSetsBackedUp - 1; i++) strbldr.AppendFormat(", {0}", itemsBackedUp[i]); if (numberOfFileSetsBackedUp > 1) strbldr.AppendFormat(FwCoreDlgs.ksIncludesAndRestoreDlg, itemsBackedUp[numberOfFileSetsBackedUp - 1]); return strbldr.ToString(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="RestoreProjectSettings"/> class from /// a list of command-line options as created from the <see cref="CommandLineOptions"/> /// property. /// </summary> /// <param name="projectsRootFolder"></param> /// <param name="projectName">Name of the project.</param> /// <param name="backupZipFileName">Name of the backup zip file.</param> /// <param name="commandLineOptions">The command line options.</param> /// ------------------------------------------------------------------------------------ public RestoreProjectSettings(string projectsRootFolder, string projectName, string backupZipFileName, string commandLineOptions) : this(projectsRootFolder) { if (string.IsNullOrEmpty(projectName)) { throw new ArgumentNullException("projectName"); } if (string.IsNullOrEmpty(backupZipFileName)) { throw new ArgumentNullException("backupZipFileName"); } if (commandLineOptions == null) { throw new ArgumentNullException("commandLineOptions"); } ProjectName = projectName; Backup = new BackupFileSettings(backupZipFileName, false); commandLineOptions = commandLineOptions.ToLowerInvariant(); IncludeConfigurationSettings = (commandLineOptions.IndexOf('c') >= 0); IncludeSupportingFiles = (commandLineOptions.IndexOf('f') >= 0); IncludeLinkedFiles = (commandLineOptions.IndexOf('l') >= 0); IncludeSpellCheckAdditions = (commandLineOptions.IndexOf('s') >= 0); }
/// ------------------------------------------------------------------------------------ /// <summary> /// The constructor initializes the dictionary for the default backup directory. /// ENHANCE: If we want this class to be able to be used for any arbitrary directory, /// we'll need to pass in the directory name or have a way to change it. /// </summary> /// ------------------------------------------------------------------------------------ public BackupFileRepository(string defaultBackupDir) { string[] backups; try { backups = FileUtils.GetFilesInDirectory(defaultBackupDir); } catch (Exception) { return; } Regex regex = new Regex(@" \d\d\d\d-\d\d?-\d\d(-| )\d\d\d\d"); foreach (string backup in backups) { string ext = Path.GetExtension(backup); if (ext != FdoFileHelper.ksFwBackupFileExtension && ext != FdoFileHelper.ksFw60BackupFileExtension) continue; string filename = Path.GetFileNameWithoutExtension(backup); MatchCollection matches = regex.Matches(filename); Debug.Assert(matches.Count <= 1, "Maybe there was a date in the comment or (perish the thought) in the project name."); if (matches.Count >= 1) { Match match = matches[0]; string projectName = filename.Substring(0, match.Index); StringBuilder date = new StringBuilder(match.Value); date.Replace("-", CultureInfo.InvariantCulture.DateTimeFormat.DateSeparator); // These next three lines are fairly ugly, but we need them to account for backups that have // a dash between the date and the time. int ichShouldBeASpace = BackupSettings.ksBackupDateFormat.Length - BackupSettings.ksBackupDateFormat.LastIndexOf(' '); Debug.Assert(ichShouldBeASpace == 5, "Rather than hard-coding a 5 here, we try to calculate this from the constant, but if this is ever not 5, someone should make sure this logic is still correct."); date[date.Length - ichShouldBeASpace] = ' '; DateTime dateOfBackup; if (DateTime.TryParseExact(date.ToString(), s_dateFormatForParsing, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out dateOfBackup)) { SortedDictionary<DateTime, BackupFileSettings> versions = GetOrCreateProjectVersions(projectName); string comment; if (ext == FdoFileHelper.ksFw60BackupFileExtension) comment = Properties.Resources.kstidFw60OrEarlierBackupComment; else { int ichStartOfComment = match.Index + match.Length + 1; comment = (ichStartOfComment < filename.Length) ? filename.Substring(ichStartOfComment) : string.Empty; } versions[dateOfBackup] = new BackupFileSettings(backup, dateOfBackup, comment); continue; } } // Try to read the contents of the zip file to see if it really is a valid FW // zip file whose filename just got mangled. BackupFileSettings settings = new BackupFileSettings(backup, false); if (IsBackupValid(settings)) { SortedDictionary<DateTime, BackupFileSettings> versions = GetOrCreateProjectVersions(settings.ProjectName); versions[settings.BackupTime] = settings; } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Perform a restore of the project specified in the settings. /// </summary> /// <param name="progressDlg">The progress dialog.</param> /// <exception cref="IOException">File does not exist, or some such problem</exception> /// <exception cref="InvalidBackupFileException">XML deserialization problem or required /// files not found in zip file</exception> /// ------------------------------------------------------------------------------------ public void RestoreProject(IThreadedProgress progressDlg) { BackupFileSettings fileSettings = m_restoreSettings.Backup; fileSettings.Validate(); // Normally, this will already have been done, so this will do nothing. bool suppressConversion = false; //First of all, if the project exists and we are overwriting it, then make a copy of the project. That way //if the restoration fails part way through, we can put it back the way it was. if (Directory.Exists(m_restoreSettings.ProjectPath)) { // If the project already exists using the fwdata extension, either we're not sharing, // or it is a project for which sharing is suppressed. In any case we don't want to // convert the new project. suppressConversion = File.Exists(m_restoreSettings.FullProjectPath); CreateACopyOfTheProject(); } //When restoring a project, ensure all the normal folders are there even if some //of those folders had nothing from them in the backup. Directory.CreateDirectory(m_restoreSettings.ProjectPath); FdoCache.CreateProjectSubfolders(m_restoreSettings.ProjectPath); try { //Import from FW version 6.0 based on the file extension. var extension = Path.GetExtension(fileSettings.File).ToLowerInvariant(); if (extension == FdoFileHelper.ksFw60BackupFileExtension || extension == ".xml") { ImportFrom6_0Backup(fileSettings, progressDlg); } else //Restore from FW version 7.0 and newer backup. { RestoreFrom7_0AndNewerBackup(fileSettings); } } catch (Exception error) { if (error is IOException || error is InvalidBackupFileException || error is UnauthorizedAccessException) { CleanupAfterRestore(false); } throw; } // switch to the desired backend (if it's in the projects directory...anything else stays XML for now). if (Path.GetDirectoryName(m_restoreSettings.ProjectPath) == m_restoreSettings.ProjectsRootFolder && !suppressConversion) { ClientServerServices.Current.Local.ConvertToDb4oBackendIfNeeded(progressDlg, m_restoreSettings.FullProjectPath); } CleanupAfterRestore(true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets a BackupFileSettings object representing the requested backup file for the /// given project. /// </summary> /// <param name="sProjectName">Name of the project.</param> /// <param name="version">The requested version.</param> /// <param name="checkValidity">if set to <c>true</c> check validity.</param> /// <returns>The BackupFileSettings object or <c>null</c> if the requested backup file /// was found to be invalid</returns> /// <exception cref="KeyNotFoundException">sProjectName is not one of the available /// projects (as returned by AvailableProjectNames) or requested version does not /// correspond to one of the avilable versions (as returned by GetAvailableVersions) /// </exception> /// ------------------------------------------------------------------------------------ public BackupFileSettings GetBackupFile(string sProjectName, DateTime version, bool checkValidity) { BackupFileSettings settings = m_availableBackups[sProjectName][version]; if (checkValidity && !IsBackupValid(settings)) { m_availableBackups[sProjectName].Remove(version); return(null); } return(settings); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Determines whether the specified backup is valid. /// </summary> /// <param name="backup">The backup settings.</param> /// ------------------------------------------------------------------------------------ private static bool IsBackupValid(BackupFileSettings backup) { try { backup.Validate(); return(true); } catch // Any errors during validate should be treated as not being valid { return(false); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Persists the dialog settings as an XML file. /// </summary> /// ------------------------------------------------------------------------------------ private void PersistBackupFileSettings() { string backupSettingsFile = Path.Combine(DirectoryFinder.GetBackupSettingsDir( m_settings.ProjectPath), DirectoryFinder.kBackupSettingsFilename); string settingsDir = Path.GetDirectoryName(backupSettingsFile); if (!Directory.Exists(settingsDir)) { Directory.CreateDirectory(settingsDir); } using (FileStream fs = new FileStream(backupSettingsFile, FileMode.Create)) { BackupFileSettings.SaveToStream(m_settings, fs); } }
private void RestoreFrom7_0AndNewerBackup(BackupFileSettings fileSettings) { // Get rid of any saved settings, since they may not be consistent with something about the data // or settings we are restoring. (This extension is also known to RecordView.GetClerkPersistPathname()). var tempDirectory = Path.Combine(m_restoreSettings.ProjectPath, DirectoryFinder.ksSortSequenceTempDir); if (Directory.Exists(tempDirectory)) { foreach (var sortSeqFile in Directory.GetFiles(tempDirectory, "*.fwss")) { File.Delete(sortSeqFile); } } UncompressDataFile(); // We can't use Path.Combine here, because the zip files stores all file paths with '/'s UncompressFilesMatchingPath(DirectoryFinder.ksWritingSystemsDir + "/", m_restoreSettings.WritingSystemStorePath); if (m_restoreSettings.IncludeSupportingFiles) { Debug.Assert(fileSettings.IncludeSupportingFiles, "The option to include supporting files should not be allowed if they aren't available in the backup settings"); var zipEntryStartsWith = DirectoryFinder.ksSupportingFilesDir; UncompressFilesContainedInFolderandSubFolders(DirectoryFinder.GetZipfileFormatedPath(zipEntryStartsWith), m_restoreSettings.ProjectSupportingFilesPath); } if (m_restoreSettings.IncludeConfigurationSettings) { UncompressFilesMatchingPath(DirectoryFinder.ksConfigurationSettingsDir + "/", m_restoreSettings.FlexConfigurationSettingsPath); } if (m_restoreSettings.IncludeLinkedFiles) { RestoreLinkedFiles(fileSettings); } if (m_restoreSettings.IncludeSpellCheckAdditions) { UncompressFilesMatchingPath(BackupSettings.ksSpellingDictionariesDir + "/", m_restoreSettings.SpellingDictionariesPath); CopySpellingOverrideFilesFromBackupToEnchant(); } }
private void ImportFrom6_0Backup(BackupFileSettings fileSettings, IThreadedProgress progressDlg) { ImportFrom6_0 importer = new ImportFrom6_0(progressDlg); string projFile; if (!importer.Import(fileSettings.File, m_restoreSettings.ProjectName, out projFile)) { ExceptionHelper.LogAndIgnoreErrors(() => CleanupFrom6_0FailedRestore(importer)); ExceptionHelper.LogAndIgnoreErrors(() => CleanupAfterRestore(false)); if (!importer.HaveOldFieldWorks || !importer.HaveFwSqlServer) { throw new MissingOldFwException("Error restoring from FieldWorks 6.0 (or earlier) backup", importer.HaveFwSqlServer, importer.HaveOldFieldWorks); } MessageBoxUtils.Show(Strings.ksRestoringOldFwBackupFailed, Strings.ksFailed); throw new FailedFwRestoreException("Error restoring from FieldWorks 6.0 (or earlier) backup"); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Reads in backup settings from the given stream, which will normally be a file, /// but for testing we can use a memory stream. /// </summary> /// <param name="persistenceStream">The persistence stream.</param> /// <exception cref="InvalidOperationException">An error occurred during deserialization. /// </exception> /// ------------------------------------------------------------------------------------ private void InitializeFromStream(Stream persistenceStream) { BackupFileSettings settings = CreateFromStream(persistenceStream); m_backupTime = settings.BackupTime; m_comment = settings.Comment; m_projectName = settings.ProjectName; m_linkedFilesPathRelative = LinkedFilesRelativePathHelper.FixPathSlashesIfNeeded(settings.LinkedFilesPathRelativePersisted); m_linkedFilesPathActual = LinkedFilesRelativePathHelper.FixPathSlashesIfNeeded(settings.LinkedFilesPathActualPersisted); m_projectPathPersisted = LinkedFilesRelativePathHelper.FixPathSlashesIfNeeded(settings.ProjectPathPersisted); m_configurationSettings = settings.IncludeConfigurationSettings; m_linkedFiles = settings.IncludeLinkedFiles; m_supportingFiles = settings.IncludeSupportingFiles; m_spellCheckAdditions = settings.IncludeSpellCheckAdditions; m_dbVersion = settings.DbVersion; m_fwVersion = settings.FwVersion; m_appAbbrev = settings.AppAbbrev; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="RestoreProjectSettings"/> class from /// a list of command-line options as created from the <see cref="CommandLineOptions"/> /// property. /// </summary> /// <param name="projectsRootFolder"></param> /// <param name="projectName">Name of the project.</param> /// <param name="backupZipFileName">Name of the backup zip file.</param> /// <param name="commandLineOptions">The command line options.</param> /// ------------------------------------------------------------------------------------ public RestoreProjectSettings(string projectsRootFolder, string projectName, string backupZipFileName, string commandLineOptions) : this(projectsRootFolder) { if (string.IsNullOrEmpty(projectName)) throw new ArgumentNullException("projectName"); if (string.IsNullOrEmpty(backupZipFileName)) throw new ArgumentNullException("backupZipFileName"); if (commandLineOptions == null) throw new ArgumentNullException("commandLineOptions"); ProjectName = projectName; Backup = new BackupFileSettings(backupZipFileName, false); commandLineOptions = commandLineOptions.ToLowerInvariant(); IncludeConfigurationSettings = (commandLineOptions.IndexOf('c') >= 0); IncludeSupportingFiles = (commandLineOptions.IndexOf('f') >= 0); IncludeLinkedFiles = (commandLineOptions.IndexOf('l') >= 0); IncludeSpellCheckAdditions = (commandLineOptions.IndexOf('s') >= 0); }
private void RestoreLinkedFiles(BackupFileSettings fileSettings) { Debug.Assert(fileSettings.LinkedFilesAvailable, "The option to include linked files should not be allowed if they aren't available in the backup settings"); var proposedDestinationLinkedFilesPath = LinkedFilesRelativePathHelper.GetLinkedFilesFullPathFromRelativePath(m_restoreSettings.ProjectsRootFolder, fileSettings.LinkedFilesPathRelativePersisted, m_restoreSettings.ProjectPath); var linkedFilesPathInZip = fileSettings.LinkedFilesPathActualPersisted; if (fileSettings.LinkedFilesPathRelativePersisted.StartsWith(LinkedFilesRelativePathHelper.ksProjectRelPath)) { // We store any files inside the project folder as a relative path from the project's directory. // Make sure we don't attempt to search for the whole directory structure in the zip file. (FWR-2909) linkedFilesPathInZip = fileSettings.LinkedFilesPathRelativePersisted.Substring( LinkedFilesRelativePathHelper.ksProjectRelPath.Length + 1); } var filesContainedInLinkdFilesFolder = GetAllFilesUnderFolderInZipFileAndDateTimes(linkedFilesPathInZip); //If the proposed location is not in the default location under the project, then ask the user if they want //to restore the files to the default location instead. Otherwise just go ahead and restore the files. var defaultLinkedFilesPath = FdoFileHelper.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); if (proposedDestinationLinkedFilesPath.Equals(defaultLinkedFilesPath)) { if (!Directory.Exists(defaultLinkedFilesPath)) { Directory.CreateDirectory(proposedDestinationLinkedFilesPath); } ExternalLinksDirectoryExits(linkedFilesPathInZip, proposedDestinationLinkedFilesPath, filesContainedInLinkdFilesFolder); } else { //LinkedFiles folder does not exist which means it was not in the default location when the backup was made. //Therefore, ask the user if we can restore these files to the default location in the project's folder. RestoreLinkedFiles(CanRestoreLinkedFilesToProjectsFolder(), filesContainedInLinkdFilesFolder, linkedFilesPathInZip, proposedDestinationLinkedFilesPath); } }
private void RestoreLinkedFiles(BackupFileSettings fileSettings) { Debug.Assert(fileSettings.LinkedFilesAvailable, "The option to include linked files should not be allowed if they aren't available in the backup settings"); var proposedDestinationLinkedFilesPath = LinkedFilesRelativePathHelper.GetLinkedFilesFullPathFromRelativePath(m_restoreSettings.ProjectsRootFolder, fileSettings.LinkedFilesPathRelativePersisted, m_restoreSettings.ProjectPath); var linkedFilesPathInZip = fileSettings.LinkedFilesPathActualPersisted; if (fileSettings.LinkedFilesPathRelativePersisted.StartsWith(LinkedFilesRelativePathHelper.ksProjectRelPath)) { // We store any files inside the project folder as a relative path from the project's directory. // Make sure we don't attempt to search for the whole directory structure in the zip file. (FWR-2909) linkedFilesPathInZip = fileSettings.LinkedFilesPathRelativePersisted.Substring( LinkedFilesRelativePathHelper.ksProjectRelPath.Length + 1); } var filesContainedInLinkdFilesFolder = GetAllFilesUnderFolderInZipFileAndDateTimes(linkedFilesPathInZip); //If the proposed location is not in the default location under the project, then ask the user if they want //to restore the files to the default location instead. Otherwise just go ahead and restore the files. var defaultLinkedFilesPath = FdoFileHelper.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); if (proposedDestinationLinkedFilesPath.Equals(defaultLinkedFilesPath)) { if (!Directory.Exists(defaultLinkedFilesPath)) Directory.CreateDirectory(proposedDestinationLinkedFilesPath); ExternalLinksDirectoryExits(linkedFilesPathInZip, proposedDestinationLinkedFilesPath, filesContainedInLinkdFilesFolder); } else { //LinkedFiles folder does not exist which means it was not in the default location when the backup was made. //Therefore, ask the user if we can restore these files to the default location in the project's folder. RestoreLinkedFiles(CanRestoreLinkedFilesToProjectsFolder(), filesContainedInLinkdFilesFolder, linkedFilesPathInZip, proposedDestinationLinkedFilesPath); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Determines whether the specified backup is valid. /// </summary> /// <param name="backup">The backup settings.</param> /// ------------------------------------------------------------------------------------ private static bool IsBackupValid(BackupFileSettings backup) { try { backup.Validate(); return true; } catch // Any errors during validate should be treated as not being valid { return false; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Called when a backup version is chosen either by browsing to a zip file. /// </summary> /// ------------------------------------------------------------------------------------ private void OnBackupVersionChosen() { m_rdoUseOriginalName.Text = String.Format(m_fmtUseOriginalName, String.Empty); m_txtOtherProjectName.Text = String.Empty; Settings.Backup = null; if (String.IsNullOrEmpty(BackupZipFile)) { EnableDisableDlgControlsForRestore(false); return; } if (HandleRestoreFileErrors(this, m_appName, BackupZipFile, () => BackupFileSettings = new BackupFileSettings(BackupZipFile, true))) { SetOriginalNameFromSettings(); } else { EnableDisableDlgControlsForRestore(false); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Sets the dialog controls from backup settings. /// </summary> /// <param name="settings">The settings.</param> /// <param name="suggestedNewProjectName">Name of the suggested new project.</param> /// ------------------------------------------------------------------------------------ private void SetDialogControlsFromBackupSettings(BackupFileSettings settings, String suggestedNewProjectName) { EnableDisableDlgControlsForRestore(true); TargetProjectName = suggestedNewProjectName; m_configurationSettings.Checked = settings.IncludeConfigurationSettings; m_configurationSettings.Enabled = settings.IncludeConfigurationSettings; // If the settings file does not contain enough information for restoring the // linked files, then just disable the option. (FWR-2245) m_linkedFiles.Checked = settings.LinkedFilesAvailable; m_linkedFiles.Enabled = settings.LinkedFilesAvailable; m_supportingFiles.Checked = settings.IncludeSupportingFiles; m_supportingFiles.Enabled = settings.IncludeSupportingFiles; m_spellCheckAdditions.Checked = settings.IncludeSpellCheckAdditions; m_spellCheckAdditions.Enabled = settings.IncludeSpellCheckAdditions; if (m_rdoDefaultFolder.Checked) m_lblDefaultBackupIncludes.Text = m_presenter.IncludesFiles(settings); else { m_lblBackupProjectName.Text = settings.ProjectName; m_lblBackupDate.Text = settings.BackupTime.ToString(); m_lblBackupComment.Text = settings.Comment; m_lblOtherBackupIncludes.Text = m_presenter.IncludesFiles(settings); } SetOriginalNameFromSettings(); }
private void RestoreLinkedFiles(BackupFileSettings fileSettings) { Debug.Assert(fileSettings.LinkedFilesAvailable, "The option to include linked files should not be allowed if they aren't available in the backup settings"); var proposedDestinationLinkedFilesPath = DirectoryFinderRelativePaths.GetLinkedFilesFullPathFromRelativePath(fileSettings.LinkedFilesPathRelativePersisted, m_restoreSettings.ProjectPath); var linkedFilesPathInZip = fileSettings.LinkedFilesPathActualPersisted; if (fileSettings.LinkedFilesPathRelativePersisted.StartsWith(DirectoryFinderRelativePaths.ksProjectRelPath)) { // We store any files inside the project folder as a relative path from the project's directory. // Make sure we don't attempt to search for the whole directory structure in the zip file. (FWR-2909) linkedFilesPathInZip = fileSettings.LinkedFilesPathRelativePersisted.Substring( DirectoryFinderRelativePaths.ksProjectRelPath.Length + 1); } var filesContainedInLinkdFilesFolder = GetAllFilesUnderFolderInZipFileAndDateTimes(linkedFilesPathInZip); //If the proposed location is not in the default location under the project, then ask the user if they want //to restore the files to the default location instead. Otherwise just go ahead and restore the files. var defaultLinkedFilesPath = DirectoryFinder.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); if (proposedDestinationLinkedFilesPath.Equals(defaultLinkedFilesPath)) { if (!Directory.Exists(defaultLinkedFilesPath)) { Directory.CreateDirectory(proposedDestinationLinkedFilesPath); } ExternalLinksDirectoryExits(linkedFilesPathInZip, proposedDestinationLinkedFilesPath, filesContainedInLinkdFilesFolder); } else { //LinkedFiles folder does not exist which means it was not in the default location when the backup was made. //Therefore, ask the user if we can restore these files to the default location in the project's folder. using (var dlg = new RestoreLinkedFilesToProjectsFolder(m_helpTopicProvider)) { if (dlg.ShowDialog() == DialogResult.OK) { if (dlg.fRestoreLinkedFilesToProjectFolder) { m_sLinkDirChangedTo = DirectoryFinder.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); //Restore the files to the project folder. UncompressLinkedFiles(filesContainedInLinkdFilesFolder, m_sLinkDirChangedTo, linkedFilesPathInZip); } else { if (!Directory.Exists(proposedDestinationLinkedFilesPath)) { try { Directory.CreateDirectory(proposedDestinationLinkedFilesPath); } catch (Exception error) { CouldNotRestoreLinkedFilesToOriginalLocation(linkedFilesPathInZip, filesContainedInLinkdFilesFolder); return; } } UncompressLinkedFiles(filesContainedInLinkdFilesFolder, proposedDestinationLinkedFilesPath, linkedFilesPathInZip); } } } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Restore a project. /// </summary> /// <param name="dialogOwner">The dialog owner.</param> /// <param name="backupFile">The file to restore from.</param> /// ------------------------------------------------------------------------------------ internal static void RestoreProject(Form dialogOwner, string backupFile) { BackupFileSettings settings = null; if (!RestoreProjectDlg.HandleRestoreFileErrors(null, FwUtils.ksSuiteName, backupFile, () => settings = new BackupFileSettings(backupFile, true))) { return; } using (RestoreProjectDlg dlg = new RestoreProjectDlg(settings, FwUtils.ksSuiteName, GetHelpTopicProvider(settings.AppAbbrev))) { dlg.ShowInTaskbar = true; if (dlg.ShowDialog(dialogOwner) != DialogResult.OK) return; HandleRestoreRequest(dialogOwner, new FwRestoreProjectSettings(settings.AppAbbrev, dlg.Settings)); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="RestoreProjectDlg"/> class. /// </summary> /// <param name="backupFileSettings">Specific backup file settings to use (dialog /// controls to select a backup file will be disabled)</param> /// <param name="appName">Name of the application (for showing in message box captions).</param> /// <param name="helpTopicProvider">The help topic provider.</param> /// ------------------------------------------------------------------------------------ public RestoreProjectDlg(BackupFileSettings backupFileSettings, string appName, IHelpTopicProvider helpTopicProvider) : this(appName, helpTopicProvider) { m_lblBackupZipFile.Text = backupFileSettings.File; m_presenter = new RestoreProjectPresenter(this); BackupFileSettings = backupFileSettings; m_rdoDefaultFolder.Enabled = m_btnBrowse.Enabled = false; m_rdoAnotherLocation.Checked = true; SetOriginalNameFromSettings(); }
private bool SetupRestore() { try { var backupSettings = new BackupFileSettings(m_restoreFileFullPath); m_restoreSettings = new RestoreProjectSettings(ParatextLexiconPluginDirectoryFinder.ProjectsDirectory) { Backup = backupSettings, IncludeConfigurationSettings = backupSettings.IncludeConfigurationSettings, IncludeLinkedFiles = backupSettings.IncludeLinkedFiles, IncludeSupportingFiles = backupSettings.IncludeSupportingFiles, IncludeSpellCheckAdditions = backupSettings.IncludeSpellCheckAdditions, BackupOfExistingProjectRequested = false }; } catch (InvalidBackupFileException ibfe) { MessageBox.Show(ibfe.Message, Strings.ksBackupFileProblemCaption, MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } catch { MessageBox.Show(Strings.ksBackupFileProblemText, Strings.ksBackupFileProblemCaption, MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// The constructor initializes the dictionary for the default backup directory. /// ENHANCE: If we want this class to be able to be used for any arbitrary directory, /// we'll need to pass in the directory name or have a way to change it. /// </summary> /// ------------------------------------------------------------------------------------ public BackupFileRepository() { string[] backups; try { backups = FileUtils.GetFilesInDirectory(DirectoryFinder.DefaultBackupDirectory); } catch (Exception) { return; } Regex regex = new Regex(@" \d\d\d\d-\d\d?-\d\d(-| )\d\d\d\d"); foreach (string backup in backups) { string ext = Path.GetExtension(backup); if (ext != FwFileExtensions.ksFwBackupFileExtension && ext != FwFileExtensions.ksFw60BackupFileExtension) { continue; } string filename = Path.GetFileNameWithoutExtension(backup); MatchCollection matches = regex.Matches(filename); Debug.Assert(matches.Count <= 1, "Maybe there was a date in the comment or (perish the thought) in the project name."); if (matches.Count >= 1) { Match match = matches[0]; string projectName = filename.Substring(0, match.Index); StringBuilder date = new StringBuilder(match.Value); date.Replace("-", CultureInfo.InvariantCulture.DateTimeFormat.DateSeparator); // These next three lines are fairly ugly, but we need them to account for backups that have // a dash between the date and the time. int ichShouldBeASpace = BackupSettings.ksBackupDateFormat.Length - BackupSettings.ksBackupDateFormat.LastIndexOf(' '); Debug.Assert(ichShouldBeASpace == 5, "Rather than hard-coding a 5 here, we try to calculate this from the constant, but if this is ever not 5, someone should make sure this logic is still correct."); date[date.Length - ichShouldBeASpace] = ' '; DateTime dateOfBackup; if (DateTime.TryParseExact(date.ToString(), s_dateFormatForParsing, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out dateOfBackup)) { SortedDictionary <DateTime, BackupFileSettings> versions = GetOrCreateProjectVersions(projectName); string comment; if (ext == FwFileExtensions.ksFw60BackupFileExtension) { comment = Properties.Resources.kstidFw60OrEarlierBackupComment; } else { int ichStartOfComment = match.Index + match.Length + 1; comment = (ichStartOfComment < filename.Length) ? filename.Substring(ichStartOfComment) : string.Empty; } versions[dateOfBackup] = new BackupFileSettings(backup, dateOfBackup, comment); continue; } } // Try to read the contents of the zip file to see if it really is a valid FW // zip file whose filename just got mangled. BackupFileSettings settings = new BackupFileSettings(backup, false); if (IsBackupValid(settings)) { SortedDictionary <DateTime, BackupFileSettings> versions = GetOrCreateProjectVersions(settings.ProjectName); versions[settings.BackupTime] = settings; } } }
private void RestoreFrom7_0AndNewerBackup(BackupFileSettings fileSettings) { // Get rid of any saved settings, since they may not be consistent with something about the data // or settings we are restoring. (This extension is also known to RecordView.GetClerkPersistPathname()). var tempDirectory = Path.Combine(m_restoreSettings.ProjectPath, FdoFileHelper.ksSortSequenceTempDir); if (Directory.Exists(tempDirectory)) { foreach (var sortSeqFile in Directory.GetFiles(tempDirectory, "*.fwss")) File.Delete(sortSeqFile); } UncompressDataFiles(); // We can't use Path.Combine here, because the zip files stores all file paths with '/'s UncompressFilesMatchingPath(FdoFileHelper.ksWritingSystemsDir + "/", m_restoreSettings.WritingSystemStorePath); if (m_restoreSettings.IncludeSupportingFiles) { Debug.Assert(fileSettings.IncludeSupportingFiles, "The option to include supporting files should not be allowed if they aren't available in the backup settings"); var zipEntryStartsWith = FdoFileHelper.ksSupportingFilesDir; UncompressFilesContainedInFolderandSubFolders(FdoFileHelper.GetZipfileFormattedPath(zipEntryStartsWith), m_restoreSettings.ProjectSupportingFilesPath); } if (m_restoreSettings.IncludeConfigurationSettings) UncompressFilesMatchingPath(FdoFileHelper.ksConfigurationSettingsDir + "/", m_restoreSettings.FlexConfigurationSettingsPath); if (m_restoreSettings.IncludeLinkedFiles) RestoreLinkedFiles(fileSettings); if (m_restoreSettings.IncludeSpellCheckAdditions) { UncompressFilesMatchingPath(BackupSettings.ksSpellingDictionariesDir + "/", m_restoreSettings.SpellingDictionariesPath); CopySpellingOverrideFilesFromBackupToLocal(); } }
public void BackupFileSettings_InitializeFromZipfileMetadata() { string zipFilePath = Path.Combine(Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/BackupRestore/RestoreProjectPresenterTests"), Path.ChangeExtension("RestoreProjectPresenterTests", FdoFileHelper.ksFwBackupFileExtension)); BackupFileSettings backupSettings = new BackupFileSettings(zipFilePath); Assert.AreEqual("BackupOnlyCoreFiles", backupSettings.Comment); Assert.AreEqual("RestoreProjectPresenterTests", backupSettings.ProjectName); //We should test the following booleans to be true since they are false by default. This means //the BackupSettings.xml file needs to have these values set to true. Assert.AreEqual(true, backupSettings.IncludeConfigurationSettings); Assert.AreEqual(true, backupSettings.IncludeLinkedFiles); Assert.AreEqual(true, backupSettings.IncludeSupportingFiles); Assert.AreEqual(true, backupSettings.IncludeSpellCheckAdditions); }