internal void InternalCopyFiles (IProgressMonitor monitor, IFileReplacePolicy replacePolicy, FileCopyConfiguration copyConfig, DeployFileCollection deployFiles, DeployContext context, string realPrefix)
		{
			string targetDirectory = ((LocalFileCopyConfiguration) copyConfig).TargetDirectory;
			
			if (string.IsNullOrEmpty (copyConfig.FriendlyLocation) || string.IsNullOrEmpty (targetDirectory))
				throw new InvalidOperationException ("Cannot deploy to unconfigured location.");
			
			List<DeployFileConf> files = new List<DeployFileConf> ();
			long totalFileSize = 0;
			
			//pre-scan: ask all copy/replace questions first so user doesn't have to wait, and get 
			foreach (DeployFile df in deployFiles) {
				if (!context.IncludeFile (df))
					continue;
				
				DeployFileConf dfc = new DeployFileConf ();
				files.Add (dfc);
				dfc.SourceFile = df.SourcePath;
				dfc.FileSize = FileSize (dfc.SourceFile);
				totalFileSize += dfc.FileSize;
				
				string relativeTarget = context.GetResolvedPath (df.TargetDirectoryID, df.RelativeTargetPath);
				if (relativeTarget == null)
					throw new InvalidOperationException (GettextCatalog.GetString ("Could not resolve target directory ID \"{0}\"", df.TargetDirectoryID));
				dfc.TargetFile = Path.Combine (targetDirectory, relativeTarget);
				
				//this is a bit hacky; it's an internal hook to the BaseFuseFileCopyHandler implementation a level up the inheritance heirarchy
				//Essentailly we are aliasing the path so that  BaseFuseFileCopyHandler can use LocalFileCopyHandler to do the local copying 
				//after the temp FUSE directory is mounted
				if (!string.IsNullOrEmpty (realPrefix)) {
					dfc.InternalTargetFile = Path.Combine (realPrefix, context.GetResolvedPath (df.TargetDirectoryID, df.RelativeTargetPath));
				} else {
					dfc.InternalTargetFile = dfc.TargetFile;
				}
				
				if (FileExists (dfc.InternalTargetFile)) {
					dfc.SourceModified = File.GetLastWriteTime (dfc.SourceFile);
					dfc.TargetModified = GetTargetModificationTime (dfc.InternalTargetFile);
					dfc.ReplaceMode = replacePolicy.GetReplaceAction (dfc.SourceFile, dfc.SourceModified, dfc.TargetFile, dfc.TargetModified);
					if (dfc.ReplaceMode == FileReplaceMode.Abort) {
						monitor.Log.WriteLine (GettextCatalog.GetString ("Deployment aborted: target file {0} already exists.", dfc.TargetFile));
						throw new OperationCanceledException ();
					}
				}
			}
			
			//PROBLEM: monitor takes ints, file sizes are longs
			//HOWEVER: longs are excessively long for a progress bar
			//SOLUTION: assume total task has a length of 1000 (longer than this is probably unnecessary for a progress bar),
			//  and set up a callback system for translating the actual long number of bytes into a portion of this
			const int progressBarLength = 1000;
			long stepSize = totalFileSize / progressBarLength;
			long carry = 0; 
			monitor.BeginTask (copyConfig.FriendlyLocation, progressBarLength);
			CopyReportCallback copyCallback = delegate (long bytes) {
				if (monitor.IsCancelRequested)
					return false;
				int steps = (int) (bytes / stepSize);
				carry += bytes % stepSize;
				if (carry > stepSize) {
					steps += 1;
					carry -= stepSize;
				}
				if (steps > 0)
					monitor.Step (steps);
				return true;
			};
			
			//now the actual copy
			foreach (DeployFileConf file in files) {
				//abort the copy if cancelling
				if (monitor.IsCancelRequested)
					break;
				
				EnsureDirectoryExists (Path.GetDirectoryName (file.InternalTargetFile));
				
				if (file.ReplaceMode != FileReplaceMode.NotSet) {
					switch (file.ReplaceMode) {
					case FileReplaceMode.Skip:
						monitor.Log.WriteLine (GettextCatalog.GetString ("Skipped {0}: file exists.", file.TargetFile));
						copyCallback (file.FileSize);
						continue; //next file
					
					case FileReplaceMode.Replace:
						monitor.Log.WriteLine (GettextCatalog.GetString ("Replaced {0}.", file.TargetFile));
						break;
					
					case FileReplaceMode.ReplaceOlder:
						if (file.SourceModified > file.TargetModified) {
							monitor.Log.WriteLine (GettextCatalog.GetString ("Replacing {0}: existing file is older.", file.TargetFile));
						} else {
							if (file.SourceModified == file.TargetModified)
								monitor.Log.WriteLine (GettextCatalog.GetString ("Skipped {0}: existing file is the same age.", file.TargetFile));
							else
								monitor.Log.WriteLine (GettextCatalog.GetString ("Skipped {0}: existing file is newer.", file.TargetFile));
							copyCallback (file.FileSize);
							continue; //next file
						}
						break;
					}
				}
				else {
					monitor.Log.WriteLine (GettextCatalog.GetString ("Deployed file {0}.", file.TargetFile));
				}
				
				CopyFile (file.SourceFile, file.InternalTargetFile, copyCallback);
			}
			
			monitor.EndTask ();
		}
Beispiel #2
0
        internal void InternalCopyFiles(IProgressMonitor monitor, IFileReplacePolicy replacePolicy, FileCopyConfiguration copyConfig, DeployFileCollection deployFiles, DeployContext context, string realPrefix)
        {
            string targetDirectory = ((LocalFileCopyConfiguration)copyConfig).TargetDirectory;

            if (string.IsNullOrEmpty(copyConfig.FriendlyLocation) || string.IsNullOrEmpty(targetDirectory))
            {
                throw new InvalidOperationException("Cannot deploy to unconfigured location.");
            }

            List <DeployFileConf> files = new List <DeployFileConf> ();
            long totalFileSize          = 0;

            //pre-scan: ask all copy/replace questions first so user doesn't have to wait, and get
            foreach (DeployFile df in deployFiles)
            {
                if (!context.IncludeFile(df))
                {
                    continue;
                }

                DeployFileConf dfc = new DeployFileConf();
                files.Add(dfc);
                dfc.SourceFile = df.SourcePath;
                dfc.FileSize   = FileSize(dfc.SourceFile);
                totalFileSize += dfc.FileSize;

                string relativeTarget = context.GetResolvedPath(df.TargetDirectoryID, df.RelativeTargetPath);
                if (relativeTarget == null)
                {
                    throw new InvalidOperationException(GettextCatalog.GetString("Could not resolve target directory ID \"{0}\"", df.TargetDirectoryID));
                }
                dfc.TargetFile = Path.Combine(targetDirectory, relativeTarget);

                //this is a bit hacky; it's an internal hook to the BaseFuseFileCopyHandler implementation a level up the inheritance heirarchy
                //Essentailly we are aliasing the path so that  BaseFuseFileCopyHandler can use LocalFileCopyHandler to do the local copying
                //after the temp FUSE directory is mounted
                if (!string.IsNullOrEmpty(realPrefix))
                {
                    dfc.InternalTargetFile = Path.Combine(realPrefix, context.GetResolvedPath(df.TargetDirectoryID, df.RelativeTargetPath));
                }
                else
                {
                    dfc.InternalTargetFile = dfc.TargetFile;
                }

                if (FileExists(dfc.InternalTargetFile))
                {
                    dfc.SourceModified = File.GetLastWriteTime(dfc.SourceFile);
                    dfc.TargetModified = GetTargetModificationTime(dfc.InternalTargetFile);
                    dfc.ReplaceMode    = replacePolicy.GetReplaceAction(dfc.SourceFile, dfc.SourceModified, dfc.TargetFile, dfc.TargetModified);
                    if (dfc.ReplaceMode == FileReplaceMode.Abort)
                    {
                        monitor.Log.WriteLine(GettextCatalog.GetString("Deployment aborted: target file {0} already exists.", dfc.TargetFile));
                        throw new OperationCanceledException();
                    }
                }
            }

            //PROBLEM: monitor takes ints, file sizes are longs
            //HOWEVER: longs are excessively long for a progress bar
            //SOLUTION: assume total task has a length of 1000 (longer than this is probably unnecessary for a progress bar),
            //  and set up a callback system for translating the actual long number of bytes into a portion of this
            const int progressBarLength = 1000;
            long      stepSize          = totalFileSize / progressBarLength;
            long      carry             = 0;

            monitor.BeginTask(copyConfig.FriendlyLocation, progressBarLength);
            CopyReportCallback copyCallback = delegate(long bytes) {
                if (monitor.IsCancelRequested)
                {
                    return(false);
                }
                int steps = (int)(bytes / stepSize);
                carry += bytes % stepSize;
                if (carry > stepSize)
                {
                    steps += 1;
                    carry -= stepSize;
                }
                if (steps > 0)
                {
                    monitor.Step(steps);
                }
                return(true);
            };

            //now the actual copy
            foreach (DeployFileConf file in files)
            {
                //abort the copy if cancelling
                if (monitor.IsCancelRequested)
                {
                    break;
                }

                EnsureDirectoryExists(Path.GetDirectoryName(file.InternalTargetFile));

                if (file.ReplaceMode != FileReplaceMode.NotSet)
                {
                    switch (file.ReplaceMode)
                    {
                    case FileReplaceMode.Skip:
                        monitor.Log.WriteLine(GettextCatalog.GetString("Skipped {0}: file exists.", file.TargetFile));
                        copyCallback(file.FileSize);
                        continue;                         //next file

                    case FileReplaceMode.Replace:
                        monitor.Log.WriteLine(GettextCatalog.GetString("Replaced {0}.", file.TargetFile));
                        break;

                    case FileReplaceMode.ReplaceOlder:
                        if (file.SourceModified > file.TargetModified)
                        {
                            monitor.Log.WriteLine(GettextCatalog.GetString("Replacing {0}: existing file is older.", file.TargetFile));
                        }
                        else
                        {
                            if (file.SourceModified == file.TargetModified)
                            {
                                monitor.Log.WriteLine(GettextCatalog.GetString("Skipped {0}: existing file is the same age.", file.TargetFile));
                            }
                            else
                            {
                                monitor.Log.WriteLine(GettextCatalog.GetString("Skipped {0}: existing file is newer.", file.TargetFile));
                            }
                            copyCallback(file.FileSize);
                            continue;                             //next file
                        }
                        break;
                    }
                }
                else
                {
                    monitor.Log.WriteLine(GettextCatalog.GetString("Deployed file {0}.", file.TargetFile));
                }

                CopyFile(file.SourceFile, file.InternalTargetFile, copyCallback);
            }

            monitor.EndTask();
        }