Fixed blocking issue
[pithos-ms-client] / trunk / Pithos.Core / Agents / SelectiveUris.cs
index 63cbbd6..94b6ac2 100644 (file)
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Text;
-using Pithos.Interfaces;
-using Pithos.Network;
-
-namespace Pithos.Core.Agents
-{
-    [Export(typeof(Selectives))]
-    public class Selectives
-    {
-
-        public Dictionary<Uri, List<Uri>> SelectiveUris { get; private set; }
-
-        private Dictionary<Uri, List<string>> SelectivePaths { get; set; }
-
-        public Selectives()
-        {
-            SelectiveUris = new Dictionary<Uri, List<Uri>>();
-            SelectivePaths = new Dictionary<Uri, List<string>>();
-        }
-
-        public void SetSelectedUris(AccountInfo account,List<Uri> uris)
-        {
-            SelectiveUris[account.AccountKey] = uris;
-            SelectivePaths[account.AccountKey] = UrisToFilePaths(account,uris);
-        }
-
-        public bool IsSelected(ObjectInfo info)
-        {
-            List<Uri> filterUris;
-            return !SelectiveUris.TryGetValue(info.AccountKey, out filterUris) 
-                || filterUris.Count ==0
-                || filterUris.Any(f => info.Uri.IsAtOrDirectlyBelow(f));
-        }
-
-        public bool IsSelected(AccountInfo account,FileSystemInfo info)
-        {
-            return IsSelected(account,info.FullName);
-        }
-
-        public bool IsSelected(AccountInfo account, string fullPath)
-        {
-            List<string> paths;
-            return !SelectivePaths.TryGetValue(account.AccountKey, out paths)
-                || paths.Count == 0
-                || paths.Any(fullPath.IsAtOrDirectlyBelow);
-        }
-
-        /// <summary>
-        /// Return a list of absolute filepaths from a list of Uris
-        /// </summary>
-        /// <param name="uris"></param>
-        /// <returns></returns>
-        private List<string> UrisToFilePaths(AccountInfo account,IEnumerable<Uri> uris)
-        {
-            if (uris == null)
-                return new List<string>();
-
-            var accountPath = account.AccountPath;
-            var storageUrl = account.StorageUri.ToString();
-            var own = (from uri in uris
-                       where uri.ToString().StartsWith(storageUrl)
-                       let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()
-                       //Trim the account name
-                       select Path.Combine(accountPath, relativePath.After(account.UserName + '\\'))).ToList();
-            var others = (from uri in uris
-                          where !uri.ToString().StartsWith(storageUrl)
-                          let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()
-                          //Trim the account name
-                          select Path.Combine(accountPath, "others-shared", relativePath)).ToList();
-            return own.Union(others).ToList();
-        }
-
-    }
-}
+using System;\r
+using System.Collections.Concurrent;\r
+using System.Collections.Generic;\r
+using System.ComponentModel.Composition;\r
+using System.Diagnostics.Contracts;\r
+using System.IO;\r
+using System.Linq;\r
+using System.Text;\r
+using Pithos.Interfaces;\r
+using Pithos.Network;\r
+\r
+namespace Pithos.Core.Agents\r
+{\r
+    [Export(typeof(Selectives))]\r
+    public class Selectives\r
+    {\r
+\r
+        public ConcurrentDictionary<Uri, ConcurrentBag<Uri>> SelectiveUris { get; private set; }\r
+\r
+        public ConcurrentDictionary<Uri, ConcurrentBag<string>> SelectivePaths { get; private set; }\r
+\r
+        [Import]\r
+        public IPithosSettings Settings { get; set; }\r
+\r
+        public Selectives()\r
+        {\r
+            SelectiveUris = new ConcurrentDictionary<Uri, ConcurrentBag<Uri>>();\r
+            SelectivePaths = new ConcurrentDictionary<Uri, ConcurrentBag<string>>();\r
+        }\r
+\r
+        readonly ConcurrentDictionary<Uri, bool> _selectiveEnabled = new ConcurrentDictionary<Uri, bool>();\r
+\r
+/*\r
+        public void SetIsSelectiveEnabled(AccountInfo account,bool value)\r
+        {\r
+            _selectiveEnabled[account.AccountKey]=value;\r
+        }\r
+*/\r
+\r
+        public void SetIsSelectiveEnabled(Uri accountKey,bool value)\r
+        {\r
+            _selectiveEnabled[accountKey]=value;\r
+        }\r
+/*\r
+\r
+        public bool IsSelectiveEnabled(AccountInfo account)\r
+        {\r
+            bool isEnabled;\r
+            _selectiveEnabled.TryGetValue(account.AccountKey, out isEnabled);\r
+            return isEnabled;\r
+        }\r
+*/\r
+\r
+        public bool IsSelectiveEnabled(Uri accountKey)\r
+        {\r
+            bool isEnabled;\r
+            _selectiveEnabled.TryGetValue(accountKey, out isEnabled);\r
+            return isEnabled;\r
+        }\r
+\r
+\r
+        public void SetSelectedUris(AccountInfo account,List<Uri> uris)\r
+        {\r
+            SelectiveUris[account.AccountKey] = new ConcurrentBag<Uri>(uris);\r
+            SelectivePaths[account.AccountKey] = new ConcurrentBag<string>(UrisToFilePaths(account,uris));\r
+        }\r
+\r
+        public void AddUri(AccountInfo account,Uri uri)\r
+        {\r
+            var accountPath = account.AccountPath;\r
+            var storageUrl = account.StorageUri.ToString();\r
+            var isShared=!uri.ToString().StartsWith(storageUrl);\r
+            var relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath();\r
+            \r
+            var fullPath=isShared\r
+                ?Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath)\r
+                :Path.Combine(accountPath, relativePath.After(account.UserName + '\\'));\r
+            \r
+            SelectiveUris[account.AccountKey].Add(uri);\r
+            SelectivePaths[account.AccountKey].Add(fullPath);\r
+            \r
+        }\r
+\r
+        public bool IsSelected(AccountInfo account,ObjectInfo info)\r
+        {\r
+            //Shared folders should NOT be synced if selective syncing is disabled\r
+            var isShared = info.IsShared??false;\r
+            if (info.StorageUri == null)\r
+                return true;\r
+            var selectiveEnabled = IsSelectiveEnabled(account.AccountKey);\r
+            if (!selectiveEnabled)\r
+                return !isShared;\r
+\r
+            ConcurrentBag<Uri> filterUris;\r
+            return SelectiveUris.TryGetValue(account.AccountKey, out filterUris) \r
+                /*|| filterUris.Count ==0*/\r
+                && filterUris.Any(f => info.Uri.IsAtOrDirectlyBelow(f));\r
+        }\r
+\r
+        public bool IsSelected(AccountInfo account,FileSystemInfo info)\r
+        {\r
+            /*if (info is DirectoryInfo)\r
+                return true;*/\r
+            return IsSelected(account,info.FullName);\r
+        }\r
+\r
+        public bool IsSelected(AccountInfo account, string fullPath)\r
+        {\r
+            //Shared folders should NOT be synced if selective syncing is disabled\r
+            var isShared = fullPath.IsSharedTo(account);\r
+            var selectiveEnabled = IsSelectiveEnabled(account.AccountKey);\r
+            if (!selectiveEnabled)\r
+                return !isShared;\r
+\r
+            ConcurrentBag<string> paths;\r
+            var hasSelectives = SelectivePaths.TryGetValue(account.AccountKey, out paths);\r
+            var isSelected = hasSelectives && paths.Any(fullPath.IsAtOrDirectlyBelow);\r
+            return isSelected;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Return a list of absolute filepaths from a list of Uris\r
+        /// </summary>\r
+        /// <param name="uris"></param>\r
+        /// <returns></returns>\r
+        private List<string> UrisToFilePaths(AccountInfo account,IEnumerable<Uri> uris)\r
+        {\r
+            if (uris == null)\r
+                return new List<string>();\r
+\r
+            var accountPath = account.AccountPath;\r
+            var storageUrl = account.StorageUri.ToString();\r
+            var own = (from uri in uris\r
+                       where uri.ToString().StartsWith(storageUrl)\r
+                       let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()\r
+                       //Trim the account name\r
+                       select Path.Combine(accountPath, relativePath.After(account.UserName + '\\'))).ToList();\r
+            var others = (from uri in uris\r
+                          where !uri.ToString().StartsWith(storageUrl)\r
+                          let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()\r
+                          //Trim the account name\r
+                          select Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath)).ToList();\r
+            return own.Union(others).ToList();\r
+        }\r
+\r
+        public void Save(AccountInfo account)\r
+        {\r
+            Contract.Requires(account!=null);\r
+            Contract.EndContractBlock();\r
+\r
+            var selections = SelectiveUris[account.AccountKey];\r
+            var accountSettings= Settings.Accounts.First(acc => acc.AccountKey == account.AccountKey);\r
+            accountSettings.SelectiveFolders.Clear();\r
+            accountSettings.SelectiveFolders.AddRange(selections.Select(uri => uri.ToString()).ToArray());\r
+            Settings.Save();   \r
+\r
+        }\r
+\r
+    }\r
+}\r