* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / nunit20 / util / AssemblyWatcher.cs
1 #region Copyright (c) 2002-2003, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole, Philip A. Craig
2 /************************************************************************************
3 '
4 ' Copyright  2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
5 ' Copyright  2000-2002 Philip A. Craig
6 '
7 ' This software is provided 'as-is', without any express or implied warranty. In no 
8 ' event will the authors be held liable for any damages arising from the use of this 
9 ' software.
10
11 ' Permission is granted to anyone to use this software for any purpose, including 
12 ' commercial applications, and to alter it and redistribute it freely, subject to the 
13 ' following restrictions:
14 '
15 ' 1. The origin of this software must not be misrepresented; you must not claim that 
16 ' you wrote the original software. If you use this software in a product, an 
17 ' acknowledgment (see the following) in the product documentation is required.
18 '
19 ' Portions Copyright  2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright  2000-2002 Philip A. Craig
21 '
22 ' 2. Altered source versions must be plainly marked as such, and must not be 
23 ' misrepresented as being the original software.
24 '
25 ' 3. This notice may not be removed or altered from any source distribution.
26 '
27 '***********************************************************************************/
28 #endregion
29
30 using System;
31 using System.IO;
32 using System.Text;
33 using System.Timers;
34 using System.Collections;
35 using NUnit.Core;
36
37 namespace NUnit.Util
38 {
39         /// <summary>
40         /// AssemblyWatcher keeps track of one or more assemblies to 
41         /// see if they have changed. It incorporates a delayed notification
42         /// and uses a standard event to notify any interested parties
43         /// about the change. The path to the assembly is provided as
44         /// an argument to the event handler so that one routine can
45         /// be used to handle events from multiple watchers.
46         /// </summary>
47         public class AssemblyWatcher
48         {
49                 FileSystemWatcher[] fileWatcher;
50                 FileInfo[] fileInfo;
51
52                 protected System.Timers.Timer timer;
53                 protected string changedAssemblyPath; 
54
55                 public delegate void AssemblyChangedHandler(String fullPath);
56                 public event AssemblyChangedHandler AssemblyChangedEvent;
57
58                 public AssemblyWatcher( int delay, string assemblyFileName )
59                         : this( delay, new string[]{ assemblyFileName } ) { }
60
61                 public AssemblyWatcher( int delay, IList assemblies )
62                 {
63                         fileInfo = new FileInfo[assemblies.Count];
64                         fileWatcher = new FileSystemWatcher[assemblies.Count];
65
66                         for( int i = 0; i < assemblies.Count; i++ )
67                         {
68                                 fileInfo[i] = new FileInfo( (string)assemblies[i] );
69
70                                 fileWatcher[i] = new FileSystemWatcher();
71                                 fileWatcher[i].Path = fileInfo[i].DirectoryName;
72                                 fileWatcher[i].Filter = fileInfo[i].Name;
73                                 fileWatcher[i].NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite;
74                                 fileWatcher[i].Changed+=new FileSystemEventHandler(OnChanged);
75                                 fileWatcher[i].EnableRaisingEvents = false;
76                         }
77
78                         timer = new System.Timers.Timer( delay );
79                         timer.AutoReset=false;
80                         timer.Enabled=false;
81                         timer.Elapsed+=new ElapsedEventHandler(OnTimer);
82                 }
83
84                 public FileInfo GetFileInfo( int index )
85                 {
86                         return fileInfo[index];
87                 }
88
89                 public void Start()
90                 {
91                         EnableWatchers( true );
92                 }
93
94                 public void Stop()
95                 {
96                         EnableWatchers( false );
97                 }
98
99                 private void EnableWatchers( bool enable )
100                 {
101                         foreach( FileSystemWatcher watcher in fileWatcher )
102                                 watcher.EnableRaisingEvents = enable;
103                 }
104
105                 protected void OnTimer(Object source, ElapsedEventArgs e)
106                 {
107                         lock(this)
108                         {
109                                 PublishEvent();
110                                 timer.Enabled=false;
111                         }
112                 }
113                 
114                 protected void OnChanged(object source, FileSystemEventArgs e)
115                 {
116                         changedAssemblyPath = e.FullPath;
117                         if ( timer != null )
118                         {
119                                 lock(this)
120                                 {
121                                         if(!timer.Enabled)
122                                                 timer.Enabled=true;
123                                         timer.Start();
124                                 }
125                         }
126                         else
127                         {
128                                 PublishEvent();
129                         }
130                 }
131         
132                 protected void PublishEvent()
133                 {
134                         if ( AssemblyChangedEvent != null )
135                                 AssemblyChangedEvent( changedAssemblyPath );
136                 }
137         }
138 }