Пример #1
0
        public void GetFullDestinationPathForItem_DoesntStartWithSlashAndDoesntContainSlash()
        {
            string expected = "Test Report";
            string actual   = SSRSUtil.GetFullDestinationPathForItem(
                "/Folder",
                "/Folder2",
                "Test Report");

            Assert.AreEqual(expected, actual);
        }
Пример #2
0
        public void GetFullDestinationPathForItem_DestinationPathEndsWithSlash()
        {
            string expected = "http://localhost/ReportServer/SSRSMigrate_NewFolder/Reports/Test Report";

            string actual = SSRSUtil.GetFullDestinationPathForItem(
                "http://localhost/ReportServer/SSRSMigrate_AW_Tests",
                "http://localhost/ReportServer/SSRSMigrate_NewFolder/",
                "http://localhost/ReportServer/SSRSMigrate_AW_Tests/Reports/Test Report");

            Assert.AreEqual(expected, actual);
        }
Пример #3
0
        public void GetFullDestinationPathForItem_InstanceAndFolderChange()
        {
            string expected = "http://localhost/ReportServer_NEWSERVER/SSRSMigrate_NewFolder/Reports/Test Report";

            string actual = SSRSUtil.GetFullDestinationPathForItem(
                "http://localhost/ReportServer/SSRSMigrate_AW_Tests",
                "http://localhost/ReportServer_NEWSERVER/SSRSMigrate_NewFolder",
                "http://localhost/ReportServer/SSRSMigrate_AW_Tests/Reports/Test Report");

            Assert.AreEqual(expected, actual);
        }
Пример #4
0
        public void GetFullDestinationPathForItem_FolderChange_CaseInsensitive()
        {
            string expected = "http://localhost/ReportServer/SSRSMigrate_NewFolder/Reports/Test Report";

            string actual = SSRSUtil.GetFullDestinationPathForItem(
                "http://localhost/ReportServer/ssrsmigrate_aw_tests",
                "http://localhost/ReportServer/SSRSMigrate_NewFolder",
                "http://localhost/ReportServer/SSRSMigrate_AW_Tests/Reports/Test Report");

            Assert.AreEqual(expected, actual);
        }
Пример #5
0
        public void GetFullDestinationPathForItem_RootFoldertoNonRootFolder_WithSubItem()
        {
            string expected = "/TEST/Test_Folder/Test_Report";

            string actual = SSRSUtil.GetFullDestinationPathForItem(
                "/",
                "/TEST",
                "/Test_Folder/Test_Report");

            Assert.AreEqual(expected, actual);
        }
Пример #6
0
        public void GetFullDestinationPathForItem_RootFolderToRootFolder()
        {
            string expected = "/Test_Report";

            string actual = SSRSUtil.GetFullDestinationPathForItem(
                "/",
                "/",
                "/Test_Report");

            Assert.AreEqual(expected, actual);
        }
Пример #7
0
        public void GetFullDestinationPathForItem_SoucePathIsInItemName()
        {
            string expected = "/SSRSMigrate_AW_Destination/Data Sources/SSRSMigrate_AW_Tests";

            string actual = SSRSUtil.GetFullDestinationPathForItem(
                "/SSRSMigrate_AW_Tests",                                  // The source root folder
                "/SSRSMigrate_AW_Destination",                            // The destination root folder
                "/SSRSMigrate_AW_Tests/Data Sources/SSRSMigrate_AW_Tests" // Complete path to source item
                );

            Assert.AreEqual(expected, actual);
        }
Пример #8
0
        public void GetFullDestinationPathForItem_SourceItemPathToDestinationItemPath()
        {
            string expected = "/SSRSMigrate_AW_Destination/Reports/Test Report";

            string actual = SSRSUtil.GetFullDestinationPathForItem(
                "/SSRSMigrate_AW_Tests",                    // The source root folder
                "/SSRSMigrate_AW_Destination",              // The destination root folder
                "/SSRSMigrate_AW_Tests/Reports/Test Report" // Complete path to source item
                );

            Assert.AreEqual(expected, actual);
        }
Пример #9
0
        public void GetFullDestinationPathForItem_EmptyItemPath()
        {
            ArgumentException ex = Assert.Throws <ArgumentException>(
                delegate
            {
                SSRSUtil.GetFullDestinationPathForItem(
                    "http://localhost/ReportServer/SSRSMigrate_AW_Tests",
                    "http://localhost/ReportServer/SSRSMigrate_NewFolder",
                    "");
            });

            Assert.That(ex.Message, Is.EqualTo("itemPath"));
        }
Пример #10
0
        public void MigrationWorker(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            string           destinationRootPath = (string)e.Argument;

            this.mLogger.Debug("MigrationWorker - destinationRootPath: {0}", destinationRootPath);

            // Stopwatch to track how long the migration takes
            Stopwatch watch = new Stopwatch();

            // Start stopwatch to get how long it takes to get the total number of checked items
            watch.Start();

            IEnumerable <ListViewItem> lvItems = GetListViewItems(this.lstSrcReports).Cast <ListViewItem>();

            // Get total count of items in ListView that are checked
            int totalItems = lvItems.Where(lv => lv.Checked == true).Count();

            // Stop stopwatch after getting the total number of checked items, and log how long it took
            watch.Stop();
            this.mLogger.Debug("MigrationWorker - Took {0} seconds to get checked ListView items", watch.Elapsed.TotalSeconds);

            // Start stopwatch to get how long it takes to migrate everything
            watch.Start();

            int progressCounter            = 0;
            int reportsMigratedCounter     = 0;
            int reportsTotalCount          = 0;
            int foldersMigratedCounter     = 0;
            int foldersTotalCount          = 0;
            int dataSourcesMigratedCounter = 0;
            int dataSourcesTotalCount      = 0;

            // Export folders
            // Get path of ListView items in the folder group that are checked.
            var folderPaths = from lv in lvItems
                              where lv.Group.Name == "foldersGroup" &&
                              lv.Checked == true
                              select((FolderItem)lv.Tag).Path;

            foldersTotalCount = folderPaths.Count();

            this.mLogger.Debug("MigrationWorker - Folder migration START!");
            this.mLogger.Debug("MigrationWorker - Migrating {0} folders...", foldersTotalCount);

            foreach (string folderPath in folderPaths)
            {
                FolderItem      folderItem = null;
                MigrationStatus status     = new MigrationStatus()
                {
                    Success = false
                };

                if (!string.IsNullOrEmpty(folderPath))
                {
                    folderItem = this.mReportServerReader.GetFolder(folderPath);

                    if (folderItem != null)
                    {
                        status.Item     = folderItem;
                        status.FromPath = folderItem.Path;

                        this.mLogger.Debug("MigrationWorker - BEFORE FolderItem.FromPath = {0}; SourceRootPath = {1}", status.FromPath, this.mSourceRootPath);
                        this.mLogger.Debug("MigrationWorker - BEFORE FolderItem.FromPath = {0}; DestinationRootPath = {1}", status.FromPath, this.mDestinationRootPath);

                        // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests/Data Sources' to '/SSRSMigrate_AW_Destination/Data Sources'
                        string destItemPath = SSRSUtil.GetFullDestinationPathForItem(
                            this.mSourceRootPath,
                            this.mDestinationRootPath,
                            folderItem.Path);

                        this.mLogger.Debug("MigrationWorker - AFTER FolderItem.FromPath = {0}; destItemPath = {1}", status.FromPath, destItemPath);

                        folderItem.Path = destItemPath;
                        status.ToPath   = destItemPath;

                        this.mLogger.Debug("MigrationWorker - FolderItem.FromPath = {0}; ToPath = {1}", status.FromPath, status.ToPath);

                        try
                        {
                            string warning = this.mReportServerWriter.WriteFolder(folderItem);

                            if (!string.IsNullOrEmpty(warning))
                            {
                                status.Warnings = new string[] { warning }
                            }
                            ;

                            status.Success = true;

                            ++foldersMigratedCounter;

                            if (this.mEngine.Loaded)
                            {
                                try
                                {
                                    this.mEngine.CallMethod("OnMigration_FolderItem", folderItem, status);
                                }
                                catch (Exception er)
                                {
                                    mLogger.Error(er, "Error calling script");


                                    this.mDebugForm.LogMessage(
                                        string.Format("Error calling script when migrating from '{0}' to '{1}': {2}",
                                                      status.FromPath,
                                                      status.ToPath,
                                                      er.Message),
                                        er);
                                }
                            }
                        }
                        catch (ItemAlreadyExistsException er)
                        {
                            this.mLogger.Error(er, "Folder item already exists.");

                            status.Success = false;
                            status.Error   = er;

                            this.mDebugForm.LogMessage(
                                string.Format("Folder can't be migrated from '{0}' to '{1}', it already exists.",
                                              status.FromPath,
                                              status.ToPath),
                                er);
                        }
                    }
                    else
                    {
                        this.mLogger.Warn("MigrationWorker - FolderItem for path '{0}' returned NULL.", folderPath);
                    }
                }

                // Always report progress, even if a ListViewItem has an empty path and even if the item isn't retrieved by ReportServerReader.
                // This will keep the progress bar value from suddenly jumping up several values.
                if (worker != null)
                {
                    worker.ReportProgress(((++progressCounter * 100) / totalItems), status);
                }
                else
                {
                    this.mLogger.Warn("MigrationWorker - worker is NULL.");
                }
            }

            this.mLogger.Debug("MigrationWorker - Folder migration END!");

            // Export data sources
            var dataSources = from lv in lvItems
                              where lv.Group.Name == "dataSourcesGroup" &&
                              lv.Checked == true
                              select(DataSourceItem) lv.Tag;

            dataSourcesTotalCount = dataSources.Count();

            this.mLogger.Debug("MigrationWorker - DataSource migration START!");
            this.mLogger.Debug("MigrationWorker - Migrating {0} datasources...", dataSourcesTotalCount);

            foreach (DataSourceItem dataSource in dataSources)
            {
                string dataSourcePath = dataSource.Path;

                DataSourceItem  dataSourceItem = null;
                MigrationStatus status         = new MigrationStatus()
                {
                    Success = false
                };

                this.mLogger.Info("MigrationWorker - Start migration of DataSource '{0}'...", dataSourcePath);

                if (!string.IsNullOrEmpty(dataSourcePath))
                {
                    dataSourceItem = this.mReportServerReader.GetDataSource(dataSourcePath);

                    if (dataSourceItem != null)
                    {
                        status.Item     = dataSourceItem;
                        status.FromPath = dataSourceItem.Path;

                        // Update the DataSource if it was changed via 'Edit Data Source...'
                        this.mLogger.Debug("MigrationWorker - Checking DataSource equality between source and destination...");
                        if (!dataSourceItem.Equals(dataSource))
                        {
                            this.mLogger.Debug("MigrationWorker - DataSources are not equal");
                            dataSourceItem = dataSource;
                        }
                        else
                        {
                            this.mLogger.Debug("MigrationWorker - DataSources are equal.");
                        }

                        this.mLogger.Debug("MigrationWorker - BEFORE DataSourceItem.FromPath = {0}; SourceRootPath = {1}", status.FromPath, this.mSourceRootPath);
                        this.mLogger.Debug("MigrationWorker - BEFORE DataSourceItem.FromPath = {0}; DestinationRootPath = {1}", status.FromPath, this.mDestinationRootPath);

                        // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests/Data Sources/AWDataSource' to '/SSRSMigrate_AW_Destination/Data Sources/AWDataSource'
                        string destItemPath = SSRSUtil.GetFullDestinationPathForItem(
                            this.mSourceRootPath,
                            this.mDestinationRootPath,
                            dataSourceItem.Path);

                        this.mLogger.Debug("MigrationWorker - AFTER DataSourceItem.FromPath = {0}; destItemPath = {1}", status.FromPath, destItemPath);

                        dataSourceItem.Path = destItemPath;
                        status.ToPath       = destItemPath;

                        this.mLogger.Debug("MigrationWorker - DataSourceItem.FromPath = {0}; ToPath = {1}", status.FromPath, status.ToPath);

                        try
                        {
                            string warning = this.mReportServerWriter.WriteDataSource(dataSourceItem);

                            if (!string.IsNullOrEmpty(warning))
                            {
                                status.Warnings = new string[] { warning }
                            }
                            ;

                            status.Success = true;

                            ++dataSourcesMigratedCounter;

                            try
                            {
                                if (this.mEngine.Loaded)
                                {
                                    this.mEngine.CallMethod("OnMigration_DataSourceItem", dataSourceItem, status);
                                }
                            }
                            catch (Exception er)
                            {
                                mLogger.Error(er, "Error calling script");


                                this.mDebugForm.LogMessage(
                                    string.Format("Error calling script when migrating from '{0}' to '{1}': {2}",
                                                  status.FromPath,
                                                  status.ToPath,
                                                  er.Message),
                                    er);
                            }
                        }
                        catch (ItemAlreadyExistsException er)
                        {
                            this.mLogger.Error(er, "Data Source item already exists.");

                            status.Success = false;
                            status.Error   = er;

                            this.mDebugForm.LogMessage(
                                string.Format("Data Source can't be migrated from '{0}' to '{1}', it already exists.",
                                              status.FromPath,
                                              status.ToPath),
                                er);
                        }
                    }
                    else
                    {
                        this.mLogger.Warn("MigrationWorker - DataSourceItem for path '{0}' returned NULL.", dataSourcePath);
                    }

                    this.mLogger.Info("MigrationWorker - End migration of DataSource '{0}'...", dataSourcePath);
                }
                else
                {
                    this.mLogger.Warn("MigrationWorker - DataSource.Path is NULL or empty or '{0}'; skipping...", dataSource.Name);
                }

                // Always report progress, even if a ListViewItem has an empty path and even if the item isn't retrieved by ReportServerReader.
                // This will keep the progress bar value from suddenly jumping up several values.
                if (worker != null)
                {
                    worker.ReportProgress(((++progressCounter * 100) / totalItems), status);
                }
                else
                {
                    this.mLogger.Warn("MigrationWorker - worker is NULL.");
                }
            }

            this.mLogger.Debug("MigrationWorker - DataSource migration END!");

            // Export reports
            var reportPaths = from lv in lvItems
                              where lv.Group.Name == "reportsGroup" &&
                              lv.Checked == true
                              select((ReportItem)lv.Tag).Path;

            reportsTotalCount = reportPaths.Count();

            this.mLogger.Debug("MigrationWorker - Report migration START!");
            this.mLogger.Debug("MigrationWorker - Migrating {0} reports...", reportsTotalCount);

            foreach (string reportPath in reportPaths)
            {
                ReportItem      reportItem = null;
                MigrationStatus status     = new MigrationStatus()
                {
                    Success = false
                };

                if (!string.IsNullOrEmpty(reportPath))
                {
                    reportItem = this.mReportServerReader.GetReport(reportPath);

                    if (reportItem != null)
                    {
                        status.Item     = reportItem;
                        status.FromPath = reportItem.Path;

                        this.mLogger.Debug(
                            "MigrationWorker - Getting destination path for '{0}' using source path root '{1}' and destination root path '{2}'...",
                            reportItem.Path,
                            this.mSourceRootPath,
                            this.mDestinationRootPath);

                        this.mLogger.Debug("MigrationWorker - BEFORE ReportItem.FromPath = {0}; SourceRootPath = {1}", status.FromPath, this.mSourceRootPath);
                        this.mLogger.Debug("MigrationWorker - BEFORE ReportItem.FromPath = {0}; DestinationRootPath = {1}", status.FromPath, this.mDestinationRootPath);

                        // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests/Reports/Company Sales' to '/SSRSMigrate_AW_Destination/Reports/Company Sales'
                        string destItemPath = SSRSUtil.GetFullDestinationPathForItem(
                            this.mSourceRootPath,
                            this.mDestinationRootPath,
                            reportItem.Path);

                        this.mLogger.Debug("MigrationWorker - AFTER ReportItem.FromPath = {0}; destItemPath = {1}", status.FromPath, destItemPath);

                        reportItem.Path = destItemPath;
                        status.ToPath   = destItemPath;

                        this.mLogger.Debug("MigrationWorker - ReportItem.FromPath = {0}; ToPath = {1}", status.FromPath, status.ToPath);

                        reportItem.Definition = SSRSUtil.UpdateReportDefinition(
                            this.mDestinationServerUrl,
                            this.mSourceRootPath,
                            this.mDestinationRootPath,
                            reportItem.Definition);

                        try
                        {
                            string[] warnings = this.mReportServerWriter.WriteReport(reportItem);

                            if (warnings != null)
                            {
                                if (warnings.Length > 0)
                                {
                                    status.Warnings = warnings;
                                }
                            }

                            status.Success = true;

                            ++reportsMigratedCounter;

                            try
                            {
                                if (this.mEngine.Loaded)
                                {
                                    this.mEngine.CallMethod("OnMigration_ReportItem", reportItem, status);
                                }
                            }
                            catch (Exception er)
                            {
                                mLogger.Error(er, "Error calling script");


                                this.mDebugForm.LogMessage(
                                    string.Format("Error calling script when migrating from '{0}' to '{1}': {2}",
                                                  status.FromPath,
                                                  status.ToPath,
                                                  er.Message),
                                    er);
                            }
                        }
                        catch (ItemAlreadyExistsException er)
                        {
                            this.mLogger.Error(er, "Report item already exists.");

                            status.Success = false;
                            status.Error   = er;

                            this.mDebugForm.LogMessage(
                                string.Format("Report can't be migrated from '{0}' to '{1}', it already exists.",
                                              status.FromPath,
                                              status.ToPath),
                                er);
                        }
                    }
                    else
                    {
                        this.mLogger.Warn("MigrationWorker - ReportItem for path '{0}' returned NULL.", reportPath);
                    }
                }

                // Always report progress, even if a ListViewItem has an empty path and even if the item isn't retrieved by ReportServerReader.
                // This will keep the progress bar value from suddenly jumping up several values.
                if (worker != null)
                {
                    worker.ReportProgress(((++progressCounter * 100) / totalItems), status);
                }
                else
                {
                    this.mLogger.Warn("MigrationWorker - worker is NULL.");
                }
            }

            this.mLogger.Debug("MigrationWorker - Report migration END!");

            // Stop stopwatch and get how long it took for the migration to complete successfully
            watch.Stop();
            double averageItem = watch.Elapsed.TotalSeconds / progressCounter;

            string result = string.Format("{0}/{1} folders, {2}/{3} data sources, {4}/{5} reports migrated in {6}h {7}m {8}s (@ {9:0.00} items/s)",
                                          foldersMigratedCounter,
                                          foldersTotalCount,
                                          dataSourcesMigratedCounter,
                                          dataSourcesTotalCount,
                                          reportsMigratedCounter,
                                          reportsTotalCount,
                                          watch.Elapsed.Hours,
                                          watch.Elapsed.Minutes,
                                          watch.Elapsed.Seconds,
                                          averageItem);

            this.mLogger.Info("MigrationWorker - {0}", result);

            e.Result = result;
        }
Пример #11
0
        private void ImportWorker(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            string           destinationRootPath = (string)e.Argument;

            // Get the source root path from the bundle
            string sourceRootPath = this.mBundleReader.Summary.SourceRootPath;

            // If the source root path is empty or null, throw an exception
            if (string.IsNullOrEmpty(sourceRootPath))
            {
                this.mLogger.Fatal("ImportWorker - SourceRootPath is NULL or empty.");

                throw new Exception("Provided 'SourceRootPath' from bundle is empty.");
            }

            this.mLogger.Debug("ImportWorker - SourceRootPath = {0}", sourceRootPath);
            this.mLogger.Debug("ImportWorker - DestinationRootPath = {0}", this.mDestinationRootPath);

            // Stopwatch to track how long the import takes
            Stopwatch watch = new Stopwatch();

            // Start stopwatch to get how long it takes to get the total number of checked items
            watch.Start();

            IEnumerable <ListViewItem> lvItems = GetListViewItems(this.lstSrcReports).Cast <ListViewItem>();

            // Get total count of items in ListView that are checked
            int totalItems = lvItems.Where(lv => lv.Checked == true).Count();

            // Stop stopwatch after getting the total number of checked items, and log how long it took
            watch.Stop();
            this.mLogger.Debug("ImportWorker - Took {0} seconds to get checked ListView items", watch.Elapsed.TotalSeconds);

            // Start stopwatch to get how long it takes to import everything
            watch.Start();

            int progressCounter            = 0;
            int reportsImportedCounter     = 0;
            int reportsTotalCount          = 0;
            int foldersImportedCounter     = 0;
            int foldersTotalCount          = 0;
            int dataSourcesImportedCounter = 0;
            int dataSourcesTotalCount      = 0;

            // Import folders
            // Get path of ListView items in the folder group that are checked.
            var folderItems =
                (from lv in lvItems
                 where lv.Group.Name == "foldersGroup" &&
                 lv.Checked == true &&
                 lv.Tag != null             // We don't want anything with a NULL Tag
                 select new
            {
                Item = (FolderItem)lv.Tag,
                ExtractedTo = lv.SubItems[4].Text
            });

            foldersTotalCount = folderItems.Count();

            // Iterate through each item that was checked in the ListView's 'foldersGroup' group
            foreach (var folderItem in folderItems)
            {
                MigrationStatus status = new MigrationStatus()
                {
                    Success  = false,
                    Item     = folderItem.Item,
                    FromPath = folderItem.ExtractedTo
                };

                // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests_Destination/Data Sources'
                string destItemPath = SSRSUtil.GetFullDestinationPathForItem(
                    sourceRootPath,
                    this.mDestinationRootPath,
                    folderItem.Item.Path);

                this.mLogger.Debug("ImportWorker - Destination path set to '{0}' for folder item '{1}'", destItemPath, folderItem.Item.Path);

                // Update the FolderItem.Path to be the new destination path
                folderItem.Item.Path = destItemPath;
                status.ToPath        = destItemPath;

                this.mLogger.Debug("ImportWorker - FolderItem.FromPath = {0}; ToPath = {1}",
                                   status.FromPath,
                                   status.ToPath);

                try
                {
                    // Write the FolderItem to the server
                    string warning = this.mReportServerWriter.WriteFolder(folderItem.Item);
                    if (!string.IsNullOrEmpty(warning))
                    {
                        status.Warnings = new string[] { warning }
                    }
                    ;

                    status.Success = true;

                    ++foldersImportedCounter;
                }
                catch (ItemAlreadyExistsException er)
                {
                    this.mLogger.Error(er, "Folder item already exists.");

                    status.Success = false;
                    status.Error   = er;

                    this.mDebugForm.LogMessage(
                        string.Format("Folder can't be imported from '{0}' to '{1}', it already exists.",
                                      status.FromPath,
                                      status.ToPath),
                        er);
                }

                // Always report progress
                if (worker != null)
                {
                    worker.ReportProgress(((++progressCounter * 100) / totalItems), status);
                }
                else
                {
                    this.mLogger.Warn("ImportWorker - worker is NULL.");
                }
            }

            // Import Data Sources
            // Get path of ListView items in the data sources group that are checked.
            var dataSourceItems =
                (from lv in lvItems
                 where lv.Group.Name == "dataSourcesGroup" &&
                 lv.Checked == true &&
                 lv.Tag != null          // We don't want anything with a NULL Tag
                 select new
            {
                Item = (DataSourceItem)lv.Tag,
                ExtractedTo = lv.SubItems[4].Text
            });

            dataSourcesTotalCount = dataSourceItems.Count();

            foreach (var dataSourceItem in dataSourceItems)
            {
                MigrationStatus status = new MigrationStatus()
                {
                    Success  = false,
                    Item     = dataSourceItem.Item,
                    FromPath = dataSourceItem.ExtractedTo
                };

                // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests_Destination/Data Sources/AWTestDataSource'
                string destItemPath = SSRSUtil.GetFullDestinationPathForItem(
                    sourceRootPath,
                    this.mDestinationRootPath,
                    dataSourceItem.Item.Path);

                this.mLogger.Debug("ImportWorker - Destination path set to '{0}' for data source item '{1}'", destItemPath, dataSourceItem.Item.Path);

                // Update the FolderItem.Path to be the new destination path
                dataSourceItem.Item.Path = destItemPath;
                status.ToPath            = destItemPath;

                this.mLogger.Debug("ImportWorker - DataSourceItem.FromPath = {0}; ToPath = {1}",
                                   status.FromPath,
                                   status.ToPath);

                try
                {
                    // Write the DataSourceItem to the server
                    string warning = this.mReportServerWriter.WriteDataSource(dataSourceItem.Item);
                    if (!string.IsNullOrEmpty(warning))
                    {
                        status.Warnings = new string[] { warning }
                    }
                    ;

                    status.Success = true;

                    ++dataSourcesImportedCounter;
                }
                catch (ItemAlreadyExistsException er)
                {
                    this.mLogger.Error(er, "Data Source already exists.");

                    status.Success = false;
                    status.Error   = er;

                    this.mDebugForm.LogMessage(
                        string.Format("Data Source can't be imported from '{0}' to '{1}', it already exists.",
                                      status.FromPath,
                                      status.ToPath),
                        er);
                }

                // Always report progress
                if (worker != null)
                {
                    worker.ReportProgress(((++progressCounter * 100) / totalItems), status);
                }
                else
                {
                    this.mLogger.Warn("ImportWorker - worker is NULL.");
                }
            }

            // Import reports
            // Get path of ListView items in the reports group that are checked.
            var reportItems =
                (from lv in lvItems
                 where lv.Group.Name == "reportsGroup" &&
                 lv.Checked == true &&
                 lv.Tag != null          // We don't want anything with a NULL Tag
                 select new
            {
                Item = (ReportItem)lv.Tag,
                ExtractedTo = lv.SubItems[4].Text
            });

            reportsTotalCount = reportItems.Count();

            foreach (var reportItem in reportItems)
            {
                MigrationStatus status = new MigrationStatus()
                {
                    Success  = false,
                    Item     = reportItem.Item,
                    FromPath = reportItem.ExtractedTo
                };

                this.mLogger.Debug(
                    "ImportWorker - Getting destination path for '{0}' using source path root '{1}' and destination root path '{2}'...",
                    reportItem.Item.Path,
                    sourceRootPath,
                    this.mDestinationRootPath);

                // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests_Destination/Reports/Company Sales'
                string destItemPath = SSRSUtil.GetFullDestinationPathForItem(
                    sourceRootPath,
                    this.mDestinationRootPath,
                    reportItem.Item.Path);

                this.mLogger.Debug("ImportWorker - Destination path set to '{0}' for report item '{1}'", destItemPath, reportItem.Item.Path);

                // Update the FolderItem.Path to be the new destination path
                reportItem.Item.Path = destItemPath;
                status.ToPath        = destItemPath;

                this.mLogger.Debug("ImportWorker - ReportItem.FromPath = {0}; ToPath = {1}",
                                   status.FromPath,
                                   status.ToPath);

                // Update the ReportItem.Definition to point to the new server
                reportItem.Item.Definition = SSRSUtil.UpdateReportDefinition(
                    this.mDestinationServerUrl,
                    sourceRootPath,
                    this.mDestinationRootPath,
                    reportItem.Item.Definition
                    );

                try
                {
                    // Write ReportItem to server
                    string[] warnings = this.mReportServerWriter.WriteReport(reportItem.Item);

                    if (warnings != null)
                    {
                        if (warnings.Length > 0)
                        {
                            status.Warnings = warnings;
                        }
                    }

                    status.Success = true;

                    ++reportsImportedCounter;
                }
                catch (ItemAlreadyExistsException er)
                {
                    this.mLogger.Error(er, "Report item already exists.");

                    status.Success = false;
                    status.Error   = er;

                    this.mDebugForm.LogMessage(
                        string.Format("Report can't be migrated from '{0}' to '{1}', it already exists.",
                                      status.FromPath,
                                      status.ToPath),
                        er);
                }

                // Always report progress
                if (worker != null)
                {
                    worker.ReportProgress(((++progressCounter * 100) / totalItems), status);
                }
                else
                {
                    this.mLogger.Warn("ImportWorker - worker is NULL.");
                }
            }

            // Stop stopwatch and get how long it took for the migration to complete successfully
            watch.Stop();
            double averageItem = watch.Elapsed.TotalSeconds / progressCounter;

            string result = string.Format("{0}/{1} folders, {2}/{3} data sources, {4}/{5} reports imported in {6}h {7}m {8}s (@ {9:0.00} items/s)",
                                          foldersImportedCounter,
                                          foldersTotalCount,
                                          dataSourcesImportedCounter,
                                          dataSourcesTotalCount,
                                          reportsImportedCounter,
                                          reportsTotalCount,
                                          watch.Elapsed.Hours,
                                          watch.Elapsed.Minutes,
                                          watch.Elapsed.Seconds,
                                          averageItem);

            this.mLogger.Info("ImportWorker - {0}", result);

            e.Result = result;
        }