Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / StatusAgent.cs @ 5e31048f

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