diff --git a/WreckCli/Controller/CliController.cs b/WreckCli/Controller/CliController.cs index 7b3eca4..511f709 100644 --- a/WreckCli/Controller/CliController.cs +++ b/WreckCli/Controller/CliController.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; +using Java.Beans; using log4net; +using Wreck.Entity; using Wreck.IO; using Wreck.IO.Task; using Wreck.Model; @@ -73,8 +75,52 @@ public override void Run(CorrectionMode mode, FileSystemInfo fsi) ITask task = Service.Run(fsi, mode, sources, corrections, customDateTime); + PropertyChangeListener propertyChangeListener = new ProgressPropertyChangeListener(this); + CliWorker pw = new CliWorker(task, fsi); - pw.Run(); + pw.AddPropertyChangeListener(propertyChangeListener); + pw.Execute(); + } + + private class ProgressPropertyChangeListener : PropertyChangeListener + { + CliController controller; + public ProgressPropertyChangeListener(CliController controller) + { + this.controller = controller; + } + + public void PropertyChange(PropertyChangeEvent evt) + { + if(R.strings.PROPERTY_STATE.Equals(evt.PropertyName)) + { + CliWorker.StateValue state = (CliWorker.StateValue) evt.NewValue; + LOG.InfoFormat( + "State = {0}", + Enum.GetName(typeof(CliWorker.StateValue), state)); + } + else if (R.strings.PROPERTY_PROGRESS.Equals(evt.PropertyName)) + { + int progress = (int)evt.NewValue; + LOG.InfoFormat("{0}%", progress); + } + else if (R.strings.PROPERTY_VISITS.Equals(evt.PropertyName)) + { + FileVisit visit = (FileVisit) evt.NewValue; + + LOG.InfoFormat("{0} - {1}%", visit.File.FullName, visit.Progress); + } + else if(R.strings.PROPERTY_BEAN.Equals(evt.PropertyName)) + { + FileBean update = (FileBean) evt.NewValue; + LOG.InfoFormat("{0}, {1}, {2}, {3}, {4}", + update.Creation.ToString(), + update.Modified.ToString(), + update.Metadata.ToString(), + update.Period.ToString(), + update.Path.FullName); + } + } } } } diff --git a/WreckCli/IO/CliVisitor.cs b/WreckCli/IO/CliVisitor.cs index aafe1e7..9337179 100644 --- a/WreckCli/IO/CliVisitor.cs +++ b/WreckCli/IO/CliVisitor.cs @@ -5,6 +5,7 @@ using Java.NIO.File; using log4net; +using Wreck.Entity; using Wreck.IO; using Wreck.Resources; using Wreck.Util.Logging; @@ -28,6 +29,9 @@ public CliVisitor(CliWorker progressWorker) : base() public override FileVisitResult PreVisitDirectory(DirectoryInfo dir) { + FileVisit visit = new FileVisit(dir); + progressWorker.Publish(visit); + base.PreVisitDirectory(dir); progressWorker.Task.PreVisitDirectory(Suggestions, dir); @@ -50,6 +54,9 @@ public override FileVisitResult VisitFile(FileInfo file) base.VisitFile(file); + FileVisit visit = new FileVisit(file); + progressWorker.Publish(visit); + progressWorker.Task.VisitFile(Suggestions, file); return FileVisitResult.Continue; diff --git a/WreckCli/IO/CliWorker.cs b/WreckCli/IO/CliWorker.cs index 7533206..b085e04 100644 --- a/WreckCli/IO/CliWorker.cs +++ b/WreckCli/IO/CliWorker.cs @@ -1,8 +1,13 @@  using System; +using System.Collections.Generic; using System.IO; + +using Java.Beans; using Java.NIO.File; +using Java.Util.Concurrent; using log4net; +using Wreck.Entity; using Wreck.IO.Task; using Wreck.Util.Logging; @@ -11,10 +16,17 @@ namespace Wreck.IO /// /// Description of CliWorker. /// - public class CliWorker + public class CliWorker : RunnableFuture { private static readonly ILog LOG = LogManager.GetLogger(typeof(CliWorker)); + protected bool cancelled; + protected int progress; + protected string result; + protected StateValue state; + + private readonly PropertyChangeSupport propertyChangeSupport; + private readonly ITask task; private readonly FileSystemInfo startPath; @@ -22,6 +34,9 @@ public class CliWorker public CliWorker(ITask task, FileSystemInfo startPath) { + state = StateValue.Pending; + propertyChangeSupport = new PropertyChangeSupport(this); + this.task = task; this.startPath = startPath; this.visitor = new CliVisitor(this); @@ -31,11 +46,154 @@ public CliWorker(ITask task, FileSystemInfo startPath) private FileSystemInfo StartPath { get { return startPath; } } private AbstractFileVisitor Visitor { get { return visitor; } } + public void Execute() + { + Run(); // Assume in a background thread. + Done(); + } + public void Run() + { + if(!cancelled) + { + SetState(StateValue.Started); + result = DoInBackground(); + } + } + + protected string DoInBackground() { Files.WalkFileTree( StartPath, Visitor); + + // Return if background worker is cancelled by user. + return IsCancelled()? "Cancelled" : "Done"; + } + + protected void Process(List chunks) + { + chunks.ForEach( + v => + { + LOG.Info(v.File.FullName); + } + ); + } + + protected void Done() + { + try + { + SetState(StateValue.Done); + string result = Get(); + LOG.DebugFormat("Done: {0}", result); + } + catch (Exception e) + { + LOG.Error(e.ToString()); + LOG.Error(e.StackTrace); + } + } + + public void AddPropertyChangeListener(PropertyChangeListener listener) + { + GetPropertyChangeSupport().AddPropertyChangeListener(listener); + } + + public void RemovePropertyChangeListener(PropertyChangeListener listener) + { + GetPropertyChangeSupport().RemovePropertyChangeListener(listener); + } + + public bool Cancel(bool mayInterruptIfRunning) + { + if(!IsCancelled() && !IsDone() && mayInterruptIfRunning) + { + cancelled = true; + return true; + } + else + return false; + } + + protected void FirePropertyChange(string propertyName, object oldValue, + object newValue) + { + LOG.DebugFormat("FirePropertyChange: {0}, {1}, {2}", + propertyName, oldValue, newValue); + GetPropertyChangeSupport().FirePropertyChange( + propertyName, + oldValue, newValue); + } + + public string Get() + { + return result; + } + + public string Get(long timeout, TimeUnit unit) + { + return Get(); + } + + public PropertyChangeSupport GetPropertyChangeSupport() + { + return propertyChangeSupport; + } + + public CliWorker.StateValue GetState() + { + if (IsDone()) + { + return StateValue.Done; + } + else + { + return state; + } + } + + private void SetState(StateValue state) + { + StateValue old = this.state; + this.state = state; + FirePropertyChange("state", old, state); + } + + public bool IsCancelled() + { + return cancelled; + } + + public bool IsDone() + { + return state == StateValue.Done; + } + + /* + protected void Process(List chunks) + { + chunks.ForEach( + chunk => + { + log.DebugFormat("Process: {0}", chunk.ToString()); + } + ); + } + */ + + public void Publish(params FileVisit[] chunks) + { + List visits = new List(chunks); + Process(visits); + } + + public enum StateValue + { + Done, + Pending, + Started } } }