示例#1
0
        /// ------------------------------------------------------------------------------------
        /// <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);
        }
示例#2
0
        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)
            {
                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");
            }
        }
示例#3
0
 /// ------------------------------------------------------------------------------------
 /// <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);
     }
 }
示例#4
0
        /// ------------------------------------------------------------------------------------
        /// <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);
        }
示例#5
0
 /// <summary>
 /// Completes initialization after deserializing the backup settings xml
 /// </summary>
 private void CompleteInitialization(BackupFileSettings settings)
 {
     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;
 }
示例#6
0
 /// <summary>
 /// Reads in the backup settings from a given archive entry, usually from a fwbackup archive.
 /// This includes a replacement operation on the xml namespace attribute to the expected namespace.
 /// </summary>
 /// <param name="zipEntry">The entry for the zip fwbackup folder.</param>
 /// <exception cref="InvalidOperationException">An error occurred during deserialization.
 /// </exception>
 private void InitializeFromZipEntry(ZipEntry zipEntry)
 {
     using (FileStream fs = System.IO.File.OpenRead(m_sZipFileName))
     {
         ZipFile   zf                = new ZipFile(fs);
         Stream    zipStream         = zf.GetInputStream(zipEntry);
         XDocument xDoc              = XDocument.Load(zipStream);
         string    backupXml         = xDoc.ToString();
         string    xmlNamespace      = @"\s+xmlns="".+\.BackupRestore""";
         string    expectedNamespace =
             @" xmlns=""http://schemas.datacontract.org/2004/07/SIL.LCModel.DomainServices.BackupRestore""";
         backupXml = Regex.Replace(backupXml, xmlNamespace, expectedNamespace);
         BackupFileSettings settings = CreateFromXml(backupXml);
         CompleteInitialization(settings);
     }
 }
示例#7
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Persists the dialog settings as an XML file.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private void PersistBackupFileSettings()
        {
            string backupSettingsFile = Path.Combine(LcmFileHelper.GetBackupSettingsDir(
                                                         m_settings.ProjectPath), LcmFileHelper.ksBackupSettingsFilename);

            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);
            }
        }
示例#8
0
        /// ------------------------------------------------------------------------------------
        /// <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.

            //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.
                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);
            LcmCache.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 == LcmFileHelper.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;
            }

            CleanupAfterRestore(true);
        }
示例#9
0
        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, LcmFileHelper.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(LcmFileHelper.ksWritingSystemsDir + "/", m_restoreSettings.WritingSystemStorePath);
            UncompressFilesMatchingPath(LexiconSettingsFileHelper.SharedSettingsFolder + "/", m_restoreSettings.SharedSettingsPath);

            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 = LcmFileHelper.ksSupportingFilesDir;
                UncompressFilesContainedInFolderandSubFolders(LcmFileHelper.GetZipfileFormattedPath(zipEntryStartsWith),
                                                              m_restoreSettings.ProjectSupportingFilesPath);
            }
            if (m_restoreSettings.IncludeConfigurationSettings)
            {
                UncompressFilesMatchingPath(LcmFileHelper.ksConfigurationSettingsDir + "/", m_restoreSettings.FlexConfigurationSettingsPath);
            }

            if (m_restoreSettings.IncludeLinkedFiles)
            {
                RestoreLinkedFiles(fileSettings);
            }

            if (m_restoreSettings.IncludeSpellCheckAdditions)
            {
                UncompressFilesMatchingPath(BackupSettings.ksSpellingDictionariesDir + "/", m_restoreSettings.SpellingDictionariesPath);

                CopySpellingOverrideFilesFromBackupToLocal();
            }
        }
示例#10
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 = LcmFileHelper.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);
            }
        }
示例#11
0
        /// ------------------------------------------------------------------------------------
        /// <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>
        /// <exception cref="SerializationException">Deserialization issue, likely from a mismatching namespace.
        /// </exception>
        /// ------------------------------------------------------------------------------------
        private void InitializeFromStream(Stream persistenceStream)
        {
            BackupFileSettings settings = CreateFromStream(persistenceStream);

            CompleteInitialization(settings);
        }
示例#12
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 != LcmFileHelper.ksFwBackupFileExtension && ext != LcmFileHelper.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 == LcmFileHelper.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;
                }
            }
        }