Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / StatusAgent.cs @ cfed7823

History | View | Annotate | Download (21 kB)

1 0eea575a Panagiotis Kanavos
using System;
2 0eea575a Panagiotis Kanavos
using System.Collections.Generic;
3 0eea575a Panagiotis Kanavos
using System.ComponentModel.Composition;
4 0eea575a Panagiotis Kanavos
using System.Diagnostics;
5 0eea575a Panagiotis Kanavos
using System.Diagnostics.Contracts;
6 0eea575a Panagiotis Kanavos
using System.IO;
7 0eea575a Panagiotis Kanavos
using System.Linq;
8 0eea575a Panagiotis Kanavos
using System.Threading;
9 0eea575a Panagiotis Kanavos
using System.Threading.Tasks;
10 0eea575a Panagiotis Kanavos
using Castle.ActiveRecord;
11 0eea575a Panagiotis Kanavos
using Castle.ActiveRecord.Framework.Config;
12 0eea575a Panagiotis Kanavos
using Pithos.Interfaces;
13 cfed7823 Panagiotis Kanavos
using log4net;
14 cfed7823 Panagiotis Kanavos
using log4net.Appender;
15 cfed7823 Panagiotis Kanavos
using log4net.Config;
16 cfed7823 Panagiotis Kanavos
using log4net.Layout;
17 0eea575a Panagiotis Kanavos
18 cfed7823 Panagiotis Kanavos
namespace Pithos.Core.Agents
19 0eea575a Panagiotis Kanavos
{
20 0eea575a Panagiotis Kanavos
    [Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))]
21 cfed7823 Panagiotis Kanavos
    public class StatusAgent:IStatusChecker,IStatusKeeper
22 0eea575a Panagiotis Kanavos
    {
23 0eea575a Panagiotis Kanavos
        [System.ComponentModel.Composition.Import]
24 0eea575a Panagiotis Kanavos
        public IPithosSettings Settings { get; set; }
25 0eea575a Panagiotis Kanavos
26 9c4346c9 Panagiotis Kanavos
        private Agent<Action> _persistenceAgent;
27 0eea575a Panagiotis Kanavos
28 cfed7823 Panagiotis Kanavos
29 cfed7823 Panagiotis Kanavos
        private static readonly ILog log = LogManager.GetLogger(typeof(StatusAgent));
30 cfed7823 Panagiotis Kanavos
31 cfed7823 Panagiotis Kanavos
        public StatusAgent()
32 3c43ec9b Panagiotis Kanavos
        {            
33 3c43ec9b Panagiotis Kanavos
            var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
34 9c4346c9 Panagiotis Kanavos
            _pithosDataPath = Path.Combine(appDataPath , "Pithos");
35 3c43ec9b Panagiotis Kanavos
36 9c4346c9 Panagiotis Kanavos
            if (!Directory.Exists(_pithosDataPath))
37 9c4346c9 Panagiotis Kanavos
                Directory.CreateDirectory(_pithosDataPath);
38 9c4346c9 Panagiotis Kanavos
39 0af3141d Panagiotis Kanavos
            //File.Delete(Path.Combine(_pithosDataPath, "pithos.db"));
40 cfed7823 Panagiotis Kanavos
            
41 9c4346c9 Panagiotis Kanavos
42 9c4346c9 Panagiotis Kanavos
            var source = GetConfiguration(_pithosDataPath);
43 9c4346c9 Panagiotis Kanavos
            ActiveRecordStarter.Initialize(source,typeof(FileState),typeof(FileTag));
44 cfed7823 Panagiotis Kanavos
            ActiveRecordStarter.UpdateSchema();
45 9c4346c9 Panagiotis Kanavos
46 9c4346c9 Panagiotis Kanavos
            ;
47 9c4346c9 Panagiotis Kanavos
            if (!File.Exists(Path.Combine(_pithosDataPath ,"pithos.db")))
48 0eea575a Panagiotis Kanavos
                ActiveRecordStarter.CreateSchema();
49 5ce54458 Panagiotis Kanavos
            
50 cfed7823 Panagiotis Kanavos
            
51 cfed7823 Panagiotis Kanavos
52 5ce54458 Panagiotis Kanavos
            CleanupStaleStates();
53 0eea575a Panagiotis Kanavos
54 cfed7823 Panagiotis Kanavos
        }        
55 9c4346c9 Panagiotis Kanavos
56 5ce54458 Panagiotis Kanavos
        private void CleanupStaleStates()
57 5ce54458 Panagiotis Kanavos
        {
58 5ce54458 Panagiotis Kanavos
            /*var stales = from state in FileState.Queryable
59 5ce54458 Panagiotis Kanavos
                         where state.FilePath.StartsWith(@"e:\pithos\fragments")
60 5ce54458 Panagiotis Kanavos
                         select state.Id;*/
61 5ce54458 Panagiotis Kanavos
            FileState.DeleteAll(@"FilePath like 'e:\pithos\fragments%'");
62 5ce54458 Panagiotis Kanavos
            ;
63 3c43ec9b Panagiotis Kanavos
        }
64 3c43ec9b Panagiotis Kanavos
65 3c43ec9b Panagiotis Kanavos
        private static InPlaceConfigurationSource GetConfiguration(string pithosDbPath)
66 3c43ec9b Panagiotis Kanavos
        {
67 9c4346c9 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(pithosDbPath))
68 9c4346c9 Panagiotis Kanavos
                throw new ArgumentNullException("pithosDbPath");
69 9c4346c9 Panagiotis Kanavos
            if (!Path.IsPathRooted(pithosDbPath))
70 9c4346c9 Panagiotis Kanavos
                throw new ArgumentException("path must be a rooted path", "pithosDbPath");
71 9c4346c9 Panagiotis Kanavos
            Contract.EndContractBlock();
72 9c4346c9 Panagiotis Kanavos
73 3c43ec9b Panagiotis Kanavos
            var properties = new Dictionary<string, string>
74 3c43ec9b Panagiotis Kanavos
                                 {
75 3c43ec9b Panagiotis Kanavos
                                     {"connection.driver_class", "NHibernate.Driver.SQLite20Driver"},
76 3c43ec9b Panagiotis Kanavos
                                     {"dialect", "NHibernate.Dialect.SQLiteDialect"},
77 3c43ec9b Panagiotis Kanavos
                                     {"connection.provider", "NHibernate.Connection.DriverConnectionProvider"},
78 3c43ec9b Panagiotis Kanavos
                                     {
79 3c43ec9b Panagiotis Kanavos
                                         "proxyfactory.factory_class",
80 3c43ec9b Panagiotis Kanavos
                                         "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"
81 3c43ec9b Panagiotis Kanavos
                                         },
82 3c43ec9b Panagiotis Kanavos
                                 };
83 3c43ec9b Panagiotis Kanavos
84 3c43ec9b Panagiotis Kanavos
            var connectionString = String.Format(@"Data Source={0}\pithos.db;Version=3", pithosDbPath);
85 3c43ec9b Panagiotis Kanavos
            properties.Add("connection.connection_string", connectionString);
86 3c43ec9b Panagiotis Kanavos
87 3c43ec9b Panagiotis Kanavos
            var source = new InPlaceConfigurationSource();
88 3c43ec9b Panagiotis Kanavos
89 3c43ec9b Panagiotis Kanavos
            source.Add(typeof (ActiveRecordBase), properties);
90 3c43ec9b Panagiotis Kanavos
            return source;
91 3c43ec9b Panagiotis Kanavos
        }
92 3c43ec9b Panagiotis Kanavos
93 3c43ec9b Panagiotis Kanavos
        public void StartProcessing(CancellationToken token)
94 3c43ec9b Panagiotis Kanavos
        {
95 9c4346c9 Panagiotis Kanavos
            _persistenceAgent = Agent<Action>.Start(queue =>
96 9c4346c9 Panagiotis Kanavos
            {
97 9c4346c9 Panagiotis Kanavos
                Action loop = null;
98 9c4346c9 Panagiotis Kanavos
                loop = () =>
99 9c4346c9 Panagiotis Kanavos
                {
100 9c4346c9 Panagiotis Kanavos
                    var job = queue.Receive();
101 9c4346c9 Panagiotis Kanavos
                    job.ContinueWith(t =>
102 9c4346c9 Panagiotis Kanavos
                    {
103 9c4346c9 Panagiotis Kanavos
                        var action = job.Result;
104 5ce54458 Panagiotis Kanavos
                        try
105 5ce54458 Panagiotis Kanavos
                        {
106 5ce54458 Panagiotis Kanavos
                            action();
107 5ce54458 Panagiotis Kanavos
                        }
108 5ce54458 Panagiotis Kanavos
                        catch (Exception ex)
109 5ce54458 Panagiotis Kanavos
                        {
110 5ce54458 Panagiotis Kanavos
                            Trace.TraceError("[ERROR] STATE \n{0}",ex);
111 5ce54458 Panagiotis Kanavos
                        }
112 9c4346c9 Panagiotis Kanavos
                        queue.DoAsync(loop);
113 9c4346c9 Panagiotis Kanavos
                    });
114 9c4346c9 Panagiotis Kanavos
                };
115 9c4346c9 Panagiotis Kanavos
                loop();
116 9c4346c9 Panagiotis Kanavos
            });
117 d15e99b4 Panagiotis Kanavos
            
118 0eea575a Panagiotis Kanavos
        }
119 0eea575a Panagiotis Kanavos
120 d15e99b4 Panagiotis Kanavos
       
121 0eea575a Panagiotis Kanavos
122 0eea575a Panagiotis Kanavos
        public void Stop()
123 0eea575a Panagiotis Kanavos
        {
124 9c4346c9 Panagiotis Kanavos
            _persistenceAgent.Stop();            
125 0eea575a Panagiotis Kanavos
        }
126 283809f3 Panagiotis Kanavos
       
127 0eea575a Panagiotis Kanavos
128 0af3141d Panagiotis Kanavos
        public void ProcessExistingFiles(IEnumerable<FileInfo> existingFiles)
129 9c4346c9 Panagiotis Kanavos
        {
130 0af3141d Panagiotis Kanavos
            if(existingFiles  ==null)
131 0af3141d Panagiotis Kanavos
                throw new ArgumentNullException("existingFiles");
132 0af3141d Panagiotis Kanavos
            Contract.EndContractBlock();
133 9c4346c9 Panagiotis Kanavos
            
134 0af3141d Panagiotis Kanavos
            //Find new or matching files with a left join to the stored states
135 0af3141d Panagiotis Kanavos
            var fileStates = FileState.Queryable;
136 0af3141d Panagiotis Kanavos
            var currentFiles=from file in existingFiles
137 0af3141d Panagiotis Kanavos
                      join state in fileStates on file.FullName.ToLower() equals state.FilePath.ToLower() into gs
138 0af3141d Panagiotis Kanavos
                      from substate in gs.DefaultIfEmpty()
139 0af3141d Panagiotis Kanavos
                               select new {File = file, State = substate};
140 0af3141d Panagiotis Kanavos
141 0af3141d Panagiotis Kanavos
            //To get the deleted files we must get the states that have no corresponding
142 0af3141d Panagiotis Kanavos
            //files. 
143 0af3141d Panagiotis Kanavos
            //We can't use the File.Exists method inside a query, so we get all file paths from the states
144 0af3141d Panagiotis Kanavos
            var statePaths = (from state in fileStates
145 0af3141d Panagiotis Kanavos
                             select new {state.Id, state.FilePath}).ToList();
146 0af3141d Panagiotis Kanavos
            //and check each one
147 0af3141d Panagiotis Kanavos
            var missingStates= (from path in statePaths
148 0af3141d Panagiotis Kanavos
                               where !File.Exists(path.FilePath)
149 0af3141d Panagiotis Kanavos
                               select path.Id).ToList();
150 0af3141d Panagiotis Kanavos
            //Finally, retrieve the states that correspond to the deleted files            
151 0af3141d Panagiotis Kanavos
            var deletedFiles = from state in fileStates 
152 0af3141d Panagiotis Kanavos
                        where missingStates.Contains(state.Id)
153 0af3141d Panagiotis Kanavos
                        select new { File = default(FileInfo), State = state };
154 0af3141d Panagiotis Kanavos
155 0af3141d Panagiotis Kanavos
            var pairs = currentFiles.Union(deletedFiles);
156 0af3141d Panagiotis Kanavos
157 0af3141d Panagiotis Kanavos
            Parallel.ForEach(pairs, pair =>
158 0eea575a Panagiotis Kanavos
            {
159 0af3141d Panagiotis Kanavos
                var fileState = pair.State;
160 0af3141d Panagiotis Kanavos
                var file = pair.File;
161 0af3141d Panagiotis Kanavos
                if (fileState == null)
162 0af3141d Panagiotis Kanavos
                {
163 0af3141d Panagiotis Kanavos
                    //This is a new file
164 0af3141d Panagiotis Kanavos
                    var fullPath = pair.File.FullName.ToLower();
165 0af3141d Panagiotis Kanavos
                    var createState = FileState.CreateForAsync(fullPath, this.BlockSize, this.BlockHash);
166 0af3141d Panagiotis Kanavos
                    createState.ContinueWith(state => _persistenceAgent.Post(state.Result.Create));
167 0af3141d Panagiotis Kanavos
                }                
168 0af3141d Panagiotis Kanavos
                else if (file == null)
169 0af3141d Panagiotis Kanavos
                {
170 0af3141d Panagiotis Kanavos
                    //This file was deleted while we were down. We should mark it as deleted
171 0af3141d Panagiotis Kanavos
                    //We have to go through UpdateStatus here because the state object we are using
172 0af3141d Panagiotis Kanavos
                    //was created by a different ORM session.
173 0af3141d Panagiotis Kanavos
                    UpdateStatus(fileState.Id,state=> state.FileStatus = FileStatus.Deleted);                    
174 0af3141d Panagiotis Kanavos
                }
175 0af3141d Panagiotis Kanavos
                else
176 0af3141d Panagiotis Kanavos
                {
177 0af3141d Panagiotis Kanavos
                    //This file has a matching state. Need to check for possible changes
178 0af3141d Panagiotis Kanavos
                    var hashString = file.CalculateHash(BlockSize,BlockHash);
179 0af3141d Panagiotis Kanavos
                    //If the hashes don't match the file was changed
180 0af3141d Panagiotis Kanavos
                    if (fileState.Checksum != hashString)
181 9c4346c9 Panagiotis Kanavos
                    {
182 0af3141d Panagiotis Kanavos
                        UpdateStatus(fileState.Id, state => state.FileStatus = FileStatus.Modified);
183 0af3141d Panagiotis Kanavos
                    }                    
184 0af3141d Panagiotis Kanavos
                }
185 0af3141d Panagiotis Kanavos
            });            
186 0af3141d Panagiotis Kanavos
         
187 0eea575a Panagiotis Kanavos
        }
188 0eea575a Panagiotis Kanavos
189 0af3141d Panagiotis Kanavos
       
190 0af3141d Panagiotis Kanavos
191 0eea575a Panagiotis Kanavos
192 9c4346c9 Panagiotis Kanavos
        public string BlockHash { get; set; }
193 9c4346c9 Panagiotis Kanavos
194 9c4346c9 Panagiotis Kanavos
        public int BlockSize { get; set; }
195 9c4346c9 Panagiotis Kanavos
196 0eea575a Panagiotis Kanavos
        private PithosStatus _pithosStatus=PithosStatus.InSynch;       
197 0eea575a Panagiotis Kanavos
198 0eea575a Panagiotis Kanavos
        public void SetPithosStatus(PithosStatus status)
199 0eea575a Panagiotis Kanavos
        {
200 0eea575a Panagiotis Kanavos
            _pithosStatus = status;
201 0eea575a Panagiotis Kanavos
        }
202 0eea575a Panagiotis Kanavos
203 0eea575a Panagiotis Kanavos
        public PithosStatus GetPithosStatus()
204 0eea575a Panagiotis Kanavos
        {
205 0eea575a Panagiotis Kanavos
            return _pithosStatus;
206 0eea575a Panagiotis Kanavos
        }
207 0eea575a Panagiotis Kanavos
208 283809f3 Panagiotis Kanavos
209 9c4346c9 Panagiotis Kanavos
        private string _pithosDataPath;
210 283809f3 Panagiotis Kanavos
211 283809f3 Panagiotis Kanavos
        public T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue )
212 283809f3 Panagiotis Kanavos
        {
213 9c4346c9 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
214 9c4346c9 Panagiotis Kanavos
                throw new ArgumentNullException("path");
215 9c4346c9 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
216 9c4346c9 Panagiotis Kanavos
                throw new ArgumentException("path must be a rooted path", "path");
217 cfed7823 Panagiotis Kanavos
            if (getter == null)
218 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("getter");
219 9c4346c9 Panagiotis Kanavos
            Contract.EndContractBlock();
220 283809f3 Panagiotis Kanavos
221 283809f3 Panagiotis Kanavos
222 283809f3 Panagiotis Kanavos
            try
223 9c4346c9 Panagiotis Kanavos
            {                
224 bfc13ed8 Panagiotis Kanavos
                var state = FileState.FindByFilePath(path);
225 283809f3 Panagiotis Kanavos
                return state == null ? defaultValue : getter(state);
226 283809f3 Panagiotis Kanavos
            }
227 283809f3 Panagiotis Kanavos
            catch (Exception exc)
228 283809f3 Panagiotis Kanavos
            {
229 283809f3 Panagiotis Kanavos
                Trace.TraceError(exc.ToString());
230 283809f3 Panagiotis Kanavos
                return defaultValue;
231 283809f3 Panagiotis Kanavos
            }
232 283809f3 Panagiotis Kanavos
        }
233 283809f3 Panagiotis Kanavos
234 283809f3 Panagiotis Kanavos
        /// <summary>
235 283809f3 Panagiotis Kanavos
        /// Sets the status of a file, creating a new FileState entry if one doesn't already exist.
236 283809f3 Panagiotis Kanavos
        /// </summary>
237 283809f3 Panagiotis Kanavos
        /// <param name="path"></param>
238 283809f3 Panagiotis Kanavos
        /// <param name="setter"></param>
239 283809f3 Panagiotis Kanavos
        public void SetStatus(string path,Action<FileState> setter)
240 283809f3 Panagiotis Kanavos
        {
241 283809f3 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
242 283809f3 Panagiotis Kanavos
                throw new ArgumentNullException("path", "path can't be empty");
243 283809f3 Panagiotis Kanavos
            if (setter==null)
244 283809f3 Panagiotis Kanavos
                throw new ArgumentNullException("setter", "setter can't be empty");
245 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
246 283809f3 Panagiotis Kanavos
247 9c4346c9 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
248 283809f3 Panagiotis Kanavos
            {
249 5ce54458 Panagiotis Kanavos
                using (new SessionScope())
250 283809f3 Panagiotis Kanavos
                {
251 5ce54458 Panagiotis Kanavos
                    var filePath = path.ToLower();
252 bfc13ed8 Panagiotis Kanavos
                    var state = FileState.FindByFilePath(filePath);
253 5ce54458 Panagiotis Kanavos
                    if (state != null)
254 5ce54458 Panagiotis Kanavos
                    {
255 5ce54458 Panagiotis Kanavos
                        setter(state);
256 5ce54458 Panagiotis Kanavos
                        state.Save();
257 5ce54458 Panagiotis Kanavos
                    }
258 5ce54458 Panagiotis Kanavos
                    else
259 5ce54458 Panagiotis Kanavos
                    {
260 5ce54458 Panagiotis Kanavos
                        state = new FileState {FilePath = filePath};
261 5ce54458 Panagiotis Kanavos
                        setter(state);
262 5ce54458 Panagiotis Kanavos
                        state.Save();
263 5ce54458 Panagiotis Kanavos
                    }                    
264 283809f3 Panagiotis Kanavos
                }
265 283809f3 Panagiotis Kanavos
            });
266 283809f3 Panagiotis Kanavos
        }
267 283809f3 Panagiotis Kanavos
268 283809f3 Panagiotis Kanavos
        /// <summary>
269 283809f3 Panagiotis Kanavos
        /// Sets the status of a file only if the file already exists
270 283809f3 Panagiotis Kanavos
        /// </summary>
271 283809f3 Panagiotis Kanavos
        /// <param name="path"></param>
272 283809f3 Panagiotis Kanavos
        /// <param name="setter"></param>
273 283809f3 Panagiotis Kanavos
        private void UpdateStatus(string path, Action<FileState> setter)
274 283809f3 Panagiotis Kanavos
        {
275 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
276 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
277 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
278 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
279 cfed7823 Panagiotis Kanavos
            if (setter == null)
280 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("setter");
281 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
282 cfed7823 Panagiotis Kanavos
283 5ce54458 Panagiotis Kanavos
            Debug.Assert(!path.Contains("fragments"));
284 5ce54458 Panagiotis Kanavos
            Debug.Assert(!path.EndsWith(".ignore"));
285 5ce54458 Panagiotis Kanavos
286 283809f3 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
287 283809f3 Panagiotis Kanavos
                throw new ArgumentNullException("path", "path can't be empty");
288 283809f3 Panagiotis Kanavos
289 283809f3 Panagiotis Kanavos
            if (setter == null)
290 283809f3 Panagiotis Kanavos
                throw new ArgumentNullException("setter", "setter can't be empty");
291 283809f3 Panagiotis Kanavos
292 9c4346c9 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
293 283809f3 Panagiotis Kanavos
            {
294 5ce54458 Panagiotis Kanavos
                using (new SessionScope())
295 283809f3 Panagiotis Kanavos
                {
296 5ce54458 Panagiotis Kanavos
                    var filePath = path.ToLower();
297 5ce54458 Panagiotis Kanavos
298 bfc13ed8 Panagiotis Kanavos
                    var state = FileState.FindByFilePath(filePath);
299 5ce54458 Panagiotis Kanavos
                    if (state == null)
300 5ce54458 Panagiotis Kanavos
                    {
301 5ce54458 Panagiotis Kanavos
                        Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", filePath);
302 5ce54458 Panagiotis Kanavos
                        return;
303 5ce54458 Panagiotis Kanavos
                    }
304 5ce54458 Panagiotis Kanavos
                    setter(state);
305 5ce54458 Panagiotis Kanavos
                    state.Save();
306 283809f3 Panagiotis Kanavos
                }
307 5ce54458 Panagiotis Kanavos
                
308 283809f3 Panagiotis Kanavos
            });
309 283809f3 Panagiotis Kanavos
        }
310 0af3141d Panagiotis Kanavos
        
311 0af3141d Panagiotis Kanavos
        /// <summary>
312 0af3141d Panagiotis Kanavos
        /// Sets the status of a specific state
313 0af3141d Panagiotis Kanavos
        /// </summary>
314 0af3141d Panagiotis Kanavos
        /// <param name="path"></param>
315 0af3141d Panagiotis Kanavos
        /// <param name="setter"></param>
316 0af3141d Panagiotis Kanavos
        private void UpdateStatus(Guid stateID, Action<FileState> setter)
317 0af3141d Panagiotis Kanavos
        {
318 cfed7823 Panagiotis Kanavos
            if (setter == null)
319 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("setter");
320 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
321 cfed7823 Panagiotis Kanavos
322 cfed7823 Panagiotis Kanavos
323 0af3141d Panagiotis Kanavos
            _persistenceAgent.Post(() =>
324 0af3141d Panagiotis Kanavos
            {
325 0af3141d Panagiotis Kanavos
                using (new SessionScope())
326 0af3141d Panagiotis Kanavos
                {
327 0af3141d Panagiotis Kanavos
                    var state = FileState.Find(stateID);
328 0af3141d Panagiotis Kanavos
                    if (state == null)
329 0af3141d Panagiotis Kanavos
                    {
330 0af3141d Panagiotis Kanavos
                        Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", stateID);
331 0af3141d Panagiotis Kanavos
                        return;
332 0af3141d Panagiotis Kanavos
                    }
333 0af3141d Panagiotis Kanavos
                    setter(state);
334 0af3141d Panagiotis Kanavos
                    state.Save();
335 0af3141d Panagiotis Kanavos
                }
336 0af3141d Panagiotis Kanavos
                
337 0af3141d Panagiotis Kanavos
            });
338 0af3141d Panagiotis Kanavos
        }
339 283809f3 Panagiotis Kanavos
340 283809f3 Panagiotis Kanavos
        public FileOverlayStatus GetFileOverlayStatus(string path)
341 283809f3 Panagiotis Kanavos
        {
342 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
343 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
344 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
345 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
346 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
347 cfed7823 Panagiotis Kanavos
348 283809f3 Panagiotis Kanavos
            try
349 283809f3 Panagiotis Kanavos
            {
350 bfc13ed8 Panagiotis Kanavos
                var state = FileState.FindByFilePath(path);
351 283809f3 Panagiotis Kanavos
                return state == null ? FileOverlayStatus.Unversioned : state.OverlayStatus;
352 283809f3 Panagiotis Kanavos
            }
353 283809f3 Panagiotis Kanavos
            catch (Exception exc)
354 283809f3 Panagiotis Kanavos
            {
355 283809f3 Panagiotis Kanavos
                Trace.TraceError(exc.ToString());
356 283809f3 Panagiotis Kanavos
                return FileOverlayStatus.Unversioned;
357 283809f3 Panagiotis Kanavos
            }
358 283809f3 Panagiotis Kanavos
        }
359 283809f3 Panagiotis Kanavos
360 0eea575a Panagiotis Kanavos
        public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus)
361 0eea575a Panagiotis Kanavos
        {
362 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
363 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
364 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
365 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted","path");
366 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
367 cfed7823 Panagiotis Kanavos
368 cfed7823 Panagiotis Kanavos
            SetStatus(path.ToLower(),s=>s.OverlayStatus=overlayStatus);
369 0eea575a Panagiotis Kanavos
        }
370 0eea575a Panagiotis Kanavos
371 cfed7823 Panagiotis Kanavos
        /*public void RemoveFileOverlayStatus(string path)
372 0eea575a Panagiotis Kanavos
        {
373 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
374 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
375 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
376 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
377 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
378 cfed7823 Panagiotis Kanavos
379 9c4346c9 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
380 0eea575a Panagiotis Kanavos
                InnerRemoveFileOverlayStatus(path));
381 0eea575a Panagiotis Kanavos
        }
382 0eea575a Panagiotis Kanavos
383 0eea575a Panagiotis Kanavos
        private static void InnerRemoveFileOverlayStatus(string path)
384 0eea575a Panagiotis Kanavos
        {
385 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
386 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
387 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
388 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
389 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
390 cfed7823 Panagiotis Kanavos
391 cfed7823 Panagiotis Kanavos
            FileState.DeleteByFilePath(path);            
392 cfed7823 Panagiotis Kanavos
        }*/
393 0eea575a Panagiotis Kanavos
394 0eea575a Panagiotis Kanavos
        public void RenameFileOverlayStatus(string oldPath, string newPath)
395 0eea575a Panagiotis Kanavos
        {
396 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(oldPath))
397 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("oldPath");
398 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(oldPath))
399 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The oldPath must be rooted", "oldPath");
400 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(newPath))
401 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("newPath");
402 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(newPath))
403 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The newPath must be rooted", "newPath");
404 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
405 cfed7823 Panagiotis Kanavos
406 9c4346c9 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
407 0eea575a Panagiotis Kanavos
                InnerRenameFileOverlayStatus(oldPath, newPath));
408 0eea575a Panagiotis Kanavos
        }
409 0eea575a Panagiotis Kanavos
410 0eea575a Panagiotis Kanavos
        private static void InnerRenameFileOverlayStatus(string oldPath, string newPath)
411 bfc13ed8 Panagiotis Kanavos
        {
412 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(oldPath))
413 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("oldPath");
414 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(oldPath))
415 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The oldPath must be rooted", "oldPath");
416 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(newPath))
417 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("newPath");
418 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(newPath))
419 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The newPath must be rooted", "newPath");
420 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
421 cfed7823 Panagiotis Kanavos
422 bfc13ed8 Panagiotis Kanavos
            var state = FileState.FindByFilePath(oldPath);
423 9c4346c9 Panagiotis Kanavos
424 0050438e Panagiotis Kanavos
            if (state == null)
425 0050438e Panagiotis Kanavos
            {
426 0050438e Panagiotis Kanavos
                Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", oldPath);
427 0050438e Panagiotis Kanavos
                return;
428 0050438e Panagiotis Kanavos
            }
429 0eea575a Panagiotis Kanavos
            //NOTE: This will cause problems if path is used as a key in relationships
430 0eea575a Panagiotis Kanavos
            state.FilePath = newPath;
431 0eea575a Panagiotis Kanavos
            state.Update();
432 0eea575a Panagiotis Kanavos
        }
433 0eea575a Panagiotis Kanavos
434 283809f3 Panagiotis Kanavos
        public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus)
435 0eea575a Panagiotis Kanavos
        {
436 283809f3 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
437 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
438 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
439 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
440 bfc13ed8 Panagiotis Kanavos
            Contract.EndContractBlock();
441 bfc13ed8 Panagiotis Kanavos
442 cfed7823 Panagiotis Kanavos
            UpdateStatus(path.ToLower(),state=>
443 283809f3 Panagiotis Kanavos
                                  {
444 283809f3 Panagiotis Kanavos
                                      state.FileStatus = fileStatus;
445 283809f3 Panagiotis Kanavos
                                      state.OverlayStatus = overlayStatus;
446 283809f3 Panagiotis Kanavos
                                  });            
447 0eea575a Panagiotis Kanavos
        }
448 0eea575a Panagiotis Kanavos
449 283809f3 Panagiotis Kanavos
        public void StoreInfo(string path,ObjectInfo objectInfo)
450 0eea575a Panagiotis Kanavos
        {
451 283809f3 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
452 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
453 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
454 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");            
455 cfed7823 Panagiotis Kanavos
            if (objectInfo == null)
456 283809f3 Panagiotis Kanavos
                throw new ArgumentNullException("objectInfo", "objectInfo can't be empty");
457 bfc13ed8 Panagiotis Kanavos
            Contract.EndContractBlock();
458 5ce54458 Panagiotis Kanavos
459 5ce54458 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
460 3c43ec9b Panagiotis Kanavos
            {
461 5ce54458 Panagiotis Kanavos
                var filePath = path.ToLower();
462 5ce54458 Panagiotis Kanavos
                //Load the existing files state and set its properties in one session            
463 5ce54458 Panagiotis Kanavos
                using (new SessionScope())
464 5ce54458 Panagiotis Kanavos
                {
465 5ce54458 Panagiotis Kanavos
                    //Forgetting to use a sessionscope results in two sessions being created, one by 
466 5ce54458 Panagiotis Kanavos
                    //FirstOrDefault and one by Save()
467 bfc13ed8 Panagiotis Kanavos
                    var state =FileState.FindByFilePath(filePath);
468 5ce54458 Panagiotis Kanavos
                    //Create a new empty state object if this is a new file
469 5ce54458 Panagiotis Kanavos
                    state = state ?? new FileState();
470 5ce54458 Panagiotis Kanavos
471 5ce54458 Panagiotis Kanavos
                    state.FilePath = filePath;
472 5ce54458 Panagiotis Kanavos
                    state.Checksum = objectInfo.Hash;
473 bfc13ed8 Panagiotis Kanavos
                    state.Version = objectInfo.Version;
474 bfc13ed8 Panagiotis Kanavos
                    state.VersionTimeStamp = objectInfo.VersionTimestamp;
475 bfc13ed8 Panagiotis Kanavos
476 5ce54458 Panagiotis Kanavos
                    state.FileStatus = FileStatus.Unchanged;
477 5ce54458 Panagiotis Kanavos
                    state.OverlayStatus = FileOverlayStatus.Normal;
478 bfc13ed8 Panagiotis Kanavos
                    
479 5ce54458 Panagiotis Kanavos
                    //Create a list of tags from the ObjectInfo's tag dictionary
480 5ce54458 Panagiotis Kanavos
                    //Make sure to bind each tag to its parent state so we don't have to save each tag separately
481 5ce54458 Panagiotis Kanavos
                    //state.Tags = (from pair in objectInfo.Tags
482 5ce54458 Panagiotis Kanavos
                    //                select
483 5ce54458 Panagiotis Kanavos
                    //                    new FileTag
484 5ce54458 Panagiotis Kanavos
                    //                        {
485 5ce54458 Panagiotis Kanavos
                    //                            FileState = state,
486 5ce54458 Panagiotis Kanavos
                    //                            Name = pair.Key,
487 5ce54458 Panagiotis Kanavos
                    //                            Value = pair.Value
488 5ce54458 Panagiotis Kanavos
                    //                        }
489 5ce54458 Panagiotis Kanavos
                    //            ).ToList();
490 5ce54458 Panagiotis Kanavos
491 5ce54458 Panagiotis Kanavos
                    //Do the save
492 5ce54458 Panagiotis Kanavos
                    state.Save();
493 5ce54458 Panagiotis Kanavos
                }
494 5ce54458 Panagiotis Kanavos
            });
495 5ce54458 Panagiotis Kanavos
496 283809f3 Panagiotis Kanavos
        }
497 283809f3 Panagiotis Kanavos
498 283809f3 Panagiotis Kanavos
        
499 283809f3 Panagiotis Kanavos
        public void SetFileStatus(string path, FileStatus status)
500 283809f3 Panagiotis Kanavos
        {            
501 cfed7823 Panagiotis Kanavos
            UpdateStatus(path.ToLower(), state=>state.FileStatus = status);
502 283809f3 Panagiotis Kanavos
        }
503 283809f3 Panagiotis Kanavos
504 0eea575a Panagiotis Kanavos
        public FileStatus GetFileStatus(string path)
505 bfc13ed8 Panagiotis Kanavos
        {
506 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
507 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
508 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
509 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
510 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
511 cfed7823 Panagiotis Kanavos
512 bfc13ed8 Panagiotis Kanavos
            var state = FileState.FindByFilePath(path);
513 0eea575a Panagiotis Kanavos
            return (state==null)?FileStatus.Missing:state.FileStatus ;
514 0eea575a Panagiotis Kanavos
        }
515 0eea575a Panagiotis Kanavos
516 0eea575a Panagiotis Kanavos
        public void ClearFileStatus(string path)
517 0eea575a Panagiotis Kanavos
        {
518 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
519 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
520 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
521 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
522 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
523 cfed7823 Panagiotis Kanavos
524 0eea575a Panagiotis Kanavos
            //TODO:SHOULDN'T need both clear file status and remove overlay status
525 cfed7823 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
526 cfed7823 Panagiotis Kanavos
            {
527 cfed7823 Panagiotis Kanavos
                using (new SessionScope())
528 cfed7823 Panagiotis Kanavos
                {
529 cfed7823 Panagiotis Kanavos
                    FileState.DeleteByFilePath(path);
530 cfed7823 Panagiotis Kanavos
                }
531 cfed7823 Panagiotis Kanavos
            });   
532 0eea575a Panagiotis Kanavos
        }
533 0eea575a Panagiotis Kanavos
534 0eea575a Panagiotis Kanavos
        public void UpdateFileChecksum(string path, string checksum)
535 cfed7823 Panagiotis Kanavos
        {
536 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
537 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
538 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
539 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");            
540 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
541 cfed7823 Panagiotis Kanavos
542 cfed7823 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
543 0050438e Panagiotis Kanavos
            {
544 5ce54458 Panagiotis Kanavos
                using (new SessionScope())
545 5ce54458 Panagiotis Kanavos
                {
546 bfc13ed8 Panagiotis Kanavos
                    var state = FileState.FindByFilePath(path);
547 5ce54458 Panagiotis Kanavos
                    if (state == null)
548 5ce54458 Panagiotis Kanavos
                    {
549 5ce54458 Panagiotis Kanavos
                        Trace.TraceWarning("[NOFILE] Unable to set checkesum for {0}.", path);
550 5ce54458 Panagiotis Kanavos
                        return;
551 5ce54458 Panagiotis Kanavos
                    }
552 5ce54458 Panagiotis Kanavos
                    state.Checksum = checksum;
553 5ce54458 Panagiotis Kanavos
                    state.Update();
554 5ce54458 Panagiotis Kanavos
                }
555 5ce54458 Panagiotis Kanavos
            });
556 0eea575a Panagiotis Kanavos
        }
557 283809f3 Panagiotis Kanavos
558 283809f3 Panagiotis Kanavos
    }
559 5ce54458 Panagiotis Kanavos
560 5ce54458 Panagiotis Kanavos
   
561 0eea575a Panagiotis Kanavos
}