UUID Changes
[pithos-ms-client] / trunk / Pithos.Core / Agents / SelectiveUris.cs
1 using System;\r
2 using System.Collections.Concurrent;\r
3 using System.Collections.Generic;\r
4 using System.ComponentModel.Composition;\r
5 using System.Diagnostics.Contracts;\r
6 using System.IO;\r
7 using System.Linq;\r
8 using System.Text;\r
9 using Pithos.Interfaces;\r
10 using Pithos.Network;\r
11 \r
12 namespace Pithos.Core.Agents\r
13 {\r
14     [Export(typeof(Selectives))]\r
15     public class Selectives\r
16     {\r
17 \r
18         public ConcurrentDictionary<Uri, ConcurrentBag<Uri>> SelectiveUris { get; private set; }\r
19 \r
20         public ConcurrentDictionary<Uri, ConcurrentBag<string>> SelectivePaths { get; private set; }\r
21 \r
22         [Import]\r
23         public IPithosSettings Settings { get; set; }\r
24 \r
25         public Selectives()\r
26         {\r
27             SelectiveUris = new ConcurrentDictionary<Uri, ConcurrentBag<Uri>>();\r
28             SelectivePaths = new ConcurrentDictionary<Uri, ConcurrentBag<string>>();\r
29         }\r
30 \r
31         readonly ConcurrentDictionary<Uri, bool> _selectiveEnabled = new ConcurrentDictionary<Uri, bool>();\r
32 \r
33 /*\r
34         public void SetIsSelectiveEnabled(AccountInfo account,bool value)\r
35         {\r
36             _selectiveEnabled[account.AccountKey]=value;\r
37         }\r
38 */\r
39 \r
40         public void SetIsSelectiveEnabled(Uri accountKey,bool value)\r
41         {\r
42             _selectiveEnabled[accountKey]=value;\r
43         }\r
44 /*\r
45 \r
46         public bool IsSelectiveEnabled(AccountInfo account)\r
47         {\r
48             bool isEnabled;\r
49             _selectiveEnabled.TryGetValue(account.AccountKey, out isEnabled);\r
50             return isEnabled;\r
51         }\r
52 */\r
53 \r
54         public bool IsSelectiveEnabled(Uri accountKey)\r
55         {\r
56             bool isEnabled;\r
57             _selectiveEnabled.TryGetValue(accountKey, out isEnabled);\r
58             return isEnabled;\r
59         }\r
60 \r
61 \r
62         public void SetSelectedUris(AccountInfo account,List<Uri> uris)\r
63         {\r
64             SelectiveUris[account.AccountKey] = new ConcurrentBag<Uri>(uris);\r
65             SelectivePaths[account.AccountKey] = new ConcurrentBag<string>(UrisToFilePaths(account,uris));\r
66         }\r
67 \r
68         public void AddUri(AccountInfo account,Uri uri)\r
69         {\r
70             var accountPath = account.AccountPath;\r
71             var storageUrl = account.StorageUri.ToString();\r
72             var isShared=!uri.ToString().StartsWith(storageUrl);\r
73             var relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath();\r
74             \r
75             var fullPath=isShared\r
76                 ?Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath)\r
77                 :Path.Combine(accountPath, relativePath.After(account.UserName + '\\'));\r
78             \r
79             SelectiveUris[account.AccountKey].Add(uri);\r
80             SelectivePaths[account.AccountKey].Add(fullPath);\r
81             \r
82         }\r
83 \r
84         public bool IsSelected(AccountInfo account,ObjectInfo info)\r
85         {\r
86             //Shared folders should NOT be synced if selective syncing is disabled\r
87             var isShared = info.IsShared??false;\r
88             if (info.StorageUri == null)\r
89                 return true;\r
90             var selectiveEnabled = IsSelectiveEnabled(account.AccountKey);\r
91             if (!selectiveEnabled)\r
92                 return !isShared;\r
93 \r
94             ConcurrentBag<Uri> filterUris;\r
95             return SelectiveUris.TryGetValue(account.AccountKey, out filterUris) \r
96                 /*|| filterUris.Count ==0*/\r
97                 && filterUris.Any(f => info.Uri.IsAtOrDirectlyBelow(f));\r
98         }\r
99 \r
100         public bool IsSelected(AccountInfo account,FileSystemInfo info)\r
101         {\r
102             /*if (info is DirectoryInfo)\r
103                 return true;*/\r
104             return IsSelected(account,info.FullName);\r
105         }\r
106 \r
107         public bool IsSelected(AccountInfo account, string fullPath)\r
108         {\r
109             //Shared folders should NOT be synced if selective syncing is disabled\r
110             var isShared = fullPath.IsSharedTo(account);\r
111             var selectiveEnabled = IsSelectiveEnabled(account.AccountKey);\r
112             if (!selectiveEnabled)\r
113                 return !isShared;\r
114 \r
115             ConcurrentBag<string> paths;\r
116             var hasSelectives = SelectivePaths.TryGetValue(account.AccountKey, out paths);\r
117             var isSelected = hasSelectives && paths.Any(fullPath.IsAtOrDirectlyBelow);\r
118             return isSelected;\r
119         }\r
120 \r
121         /// <summary>\r
122         /// Return a list of absolute filepaths from a list of Uris\r
123         /// </summary>\r
124         /// <param name="uris"></param>\r
125         /// <returns></returns>\r
126         private List<string> UrisToFilePaths(AccountInfo account,IEnumerable<Uri> uris)\r
127         {\r
128             if (uris == null)\r
129                 return new List<string>();\r
130 \r
131             var accountPath = account.AccountPath;\r
132             var storageUrl = account.StorageUri.ToString();\r
133             var own = (from uri in uris\r
134                        where uri.ToString().StartsWith(storageUrl)\r
135                        let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()\r
136                        //Trim the account name\r
137                        select Path.Combine(accountPath, relativePath.After(account.UserName + '\\'))).ToList();\r
138             var others = (from uri in uris\r
139                           where !uri.ToString().StartsWith(storageUrl)\r
140                           let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()\r
141                           //Trim the account name\r
142                           select Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath)).ToList();\r
143             return own.Union(others).ToList();\r
144         }\r
145 \r
146         public void Save(AccountInfo account)\r
147         {\r
148             Contract.Requires(account!=null);\r
149             Contract.EndContractBlock();\r
150 \r
151             var selections = SelectiveUris[account.AccountKey];\r
152             var accountSettings= Settings.Accounts.FirstOrDefault(acc => acc.AccountKey == account.AccountKey);\r
153             if (accountSettings == null)\r
154                 return;\r
155             accountSettings.SelectiveFolders.Clear();\r
156             accountSettings.SelectiveFolders.AddRange(selections.Select(uri => uri.ToString()).ToArray());\r
157             Settings.Save();   \r
158 \r
159         }\r
160 \r
161     }\r
162 }\r