Revision 69588a95 trunk/Pithos.Client.WPF/Utils/EnumerableExtensions.cs
b/trunk/Pithos.Client.WPF/Utils/EnumerableExtensions.cs | ||
---|---|---|
4 | 4 |
using System.Linq; |
5 | 5 |
using System.Linq.Expressions; |
6 | 6 |
using System.Text; |
7 |
using System.Text.RegularExpressions; |
|
7 | 8 |
using Pithos.Client.WPF.SelectiveSynch; |
9 |
using Pithos.Core; |
|
8 | 10 |
using Pithos.Interfaces; |
9 | 11 |
|
10 | 12 |
namespace Pithos.Client.WPF.Utils |
... | ... | |
79 | 81 |
|
80 | 82 |
public static List<DirectoryRecord> ToTree(this IEnumerable<ObjectInfo> enumerable) |
81 | 83 |
{ |
84 |
//Order the items to ensure that children always come after their parents |
|
82 | 85 |
var orderedItems=enumerable.OrderBy(o=>o.Uri.ToString()); |
86 |
//Each item is stored in lookups |
|
83 | 87 |
var lookups = new Dictionary<string,DirectoryRecord>(); |
84 |
var nodes = new List<DirectoryRecord>(); |
|
88 |
|
|
89 |
//RootNodes contains only the root nodes |
|
90 |
var rootNodes = new List<DirectoryRecord>(); |
|
91 |
|
|
85 | 92 |
foreach (var item in orderedItems) |
86 | 93 |
{ |
87 | 94 |
var path = item.Uri.ToString(); |
88 |
var newNode = new DirectoryRecord{ DisplayName=item.Name.Split('/').Last(),ObjectInfo=item}; |
|
89 |
lookups[path] = newNode; |
|
90 |
|
|
91 |
var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal); |
|
92 |
var upTo = lastIndex < 0 ? path.Length - 1 : lastIndex; |
|
93 |
var parentPath = path.Substring(0, upTo); |
|
94 |
|
|
95 |
//Calculate the parent path |
|
96 |
var parentPath = GetParentPath(path); |
|
97 |
var parentName = GetParentPath(item.Name); |
|
95 | 98 |
DirectoryRecord parent; |
96 |
if (lookups.TryGetValue(parentPath, out parent)) |
|
99 |
DirectoryRecord newNode; |
|
100 |
|
|
101 |
//Dont't add files |
|
102 |
if (!item.IsDirectory) |
|
97 | 103 |
{ |
98 |
parent.Directories.Add(newNode); |
|
99 |
parent.Directories.Sort((x,y)=>String.CompareOrdinal(x.Uri.ToString(), y.Uri.ToString())); |
|
104 |
//But check to ensure that we DO have it's parent on record |
|
105 |
//It it exist |
|
106 |
if (lookups.TryGetValue(parentPath, out parent)) |
|
107 |
{ |
|
108 |
//Just continue |
|
109 |
continue; |
|
110 |
} |
|
111 |
//If the item is directly below its parent container, there is no path to add |
|
112 |
if (String.IsNullOrWhiteSpace(parentName)) |
|
113 |
continue; |
|
114 |
//Otherwise we need to add it, because it is missing from the list |
|
115 |
//Store each item using its current path |
|
116 |
newNode = new DirectoryRecord { DisplayName = parentPath.Split('/').Last(), |
|
117 |
ObjectInfo = new ObjectInfo{Account=item.Account,Container=item.Container,Name=parentPath,Content_Type="application/directory"}}; |
|
100 | 118 |
} |
101 | 119 |
else |
102 |
nodes.Add(newNode); |
|
120 |
{ |
|
121 |
//Store each item using its current path |
|
122 |
newNode = new DirectoryRecord {DisplayName = item.Name.Split('/').Last(), ObjectInfo = item}; |
|
123 |
} |
|
124 |
AddNode(rootNodes, parentPath, path, lookups, newNode); |
|
125 |
} |
|
126 |
return rootNodes; |
|
127 |
} |
|
128 |
|
|
129 |
private static void AddNode(List<DirectoryRecord> rootNodes, string parentPath, string path, Dictionary<string, DirectoryRecord> lookups, DirectoryRecord newNode) |
|
130 |
{ |
|
131 |
DirectoryRecord parent; |
|
132 |
lookups[path] = newNode; |
|
103 | 133 |
|
134 |
|
|
135 |
//Does a parent item exist? |
|
136 |
if (lookups.TryGetValue(parentPath, out parent)) |
|
137 |
{ |
|
138 |
//If so, add the current item under its parent |
|
139 |
parent.Directories.Add(newNode); |
|
140 |
parent.Directories.Sort((x, y) => String.CompareOrdinal(x.Uri.ToString(), y.Uri.ToString())); |
|
104 | 141 |
} |
105 |
return nodes; |
|
142 |
else |
|
143 |
//Otherwise add it to the list of root nodes |
|
144 |
rootNodes.Add(newNode); |
|
145 |
} |
|
146 |
|
|
147 |
private static string GetParentPath(string path) |
|
148 |
{ |
|
149 |
var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal); |
|
150 |
if (lastIndex < 0) |
|
151 |
return null; |
|
152 |
var parentPath = path.Substring(0, lastIndex); |
|
153 |
return parentPath; |
|
154 |
} |
|
155 |
|
|
156 |
static readonly Regex PascalCaseRegex = new Regex("[a-z][A-Z]", RegexOptions.Compiled); |
|
157 |
public static string Name(this Enum value) |
|
158 |
{ |
|
159 |
var name = Enum.GetName(value.GetType(), value); |
|
160 |
return PascalCaseRegex.Replace(name, m => m.Value[0] + " " + char.ToLower(m.Value[1])); |
|
106 | 161 |
} |
107 | 162 |
} |
108 | 163 |
} |
Also available in: Unified diff