using System.Linq;
using System.Linq.Expressions;
using System.Text;
+using System.Text.RegularExpressions;
using Pithos.Client.WPF.SelectiveSynch;
+using Pithos.Core;
using Pithos.Interfaces;
namespace Pithos.Client.WPF.Utils
public static List<DirectoryRecord> ToTree(this IEnumerable<ObjectInfo> enumerable)
{
+ //Order the items to ensure that children always come after their parents
var orderedItems=enumerable.OrderBy(o=>o.Uri.ToString());
+ //Each item is stored in lookups
var lookups = new Dictionary<string,DirectoryRecord>();
- var nodes = new List<DirectoryRecord>();
+
+ //RootNodes contains only the root nodes
+ var rootNodes = new List<DirectoryRecord>();
+
foreach (var item in orderedItems)
{
var path = item.Uri.ToString();
- var newNode = new DirectoryRecord{ DisplayName=item.Name.Split('/').Last(),ObjectInfo=item};
- lookups[path] = newNode;
-
- var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal);
- var upTo = lastIndex < 0 ? path.Length - 1 : lastIndex;
- var parentPath = path.Substring(0, upTo);
-
+ //Calculate the parent path
+ var parentPath = GetParentPath(path);
+ var parentName = GetParentPath(item.Name);
DirectoryRecord parent;
- if (lookups.TryGetValue(parentPath, out parent))
+ DirectoryRecord newNode;
+
+ //Dont't add files
+ if (!item.IsDirectory)
{
- parent.Directories.Add(newNode);
- parent.Directories.Sort((x,y)=>String.CompareOrdinal(x.Uri.ToString(), y.Uri.ToString()));
+ //But check to ensure that we DO have it's parent on record
+ //It it exist
+ if (lookups.TryGetValue(parentPath, out parent))
+ {
+ //Just continue
+ continue;
+ }
+ //If the item is directly below its parent container, there is no path to add
+ if (String.IsNullOrWhiteSpace(parentName))
+ continue;
+ //Otherwise we need to add it, because it is missing from the list
+ //Store each item using its current path
+ newNode = new DirectoryRecord { DisplayName = parentPath.Split('/').Last(),
+ ObjectInfo = new ObjectInfo{Account=item.Account,Container=item.Container,Name=parentPath,Content_Type="application/directory"}};
}
else
- nodes.Add(newNode);
+ {
+ //Store each item using its current path
+ newNode = new DirectoryRecord {DisplayName = item.Name.Split('/').Last(), ObjectInfo = item};
+ }
+ AddNode(rootNodes, parentPath, path, lookups, newNode);
+ }
+ return rootNodes;
+ }
+
+ private static void AddNode(List<DirectoryRecord> rootNodes, string parentPath, string path, Dictionary<string, DirectoryRecord> lookups, DirectoryRecord newNode)
+ {
+ DirectoryRecord parent;
+ lookups[path] = newNode;
+
+ //Does a parent item exist?
+ if (lookups.TryGetValue(parentPath, out parent))
+ {
+ //If so, add the current item under its parent
+ parent.Directories.Add(newNode);
+ parent.Directories.Sort((x, y) => String.CompareOrdinal(x.Uri.ToString(), y.Uri.ToString()));
}
- return nodes;
+ else
+ //Otherwise add it to the list of root nodes
+ rootNodes.Add(newNode);
+ }
+
+ private static string GetParentPath(string path)
+ {
+ var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal);
+ if (lastIndex < 0)
+ return null;
+ var parentPath = path.Substring(0, lastIndex);
+ return parentPath;
+ }
+
+ static readonly Regex PascalCaseRegex = new Regex("[a-z][A-Z]", RegexOptions.Compiled);
+ public static string Name(this Enum value)
+ {
+ var name = Enum.GetName(value.GetType(), value);
+ return PascalCaseRegex.Replace(name, m => m.Value[0] + " " + char.ToLower(m.Value[1]));
}
}
}