Fix for missing directories
[pithos-ms-client] / trunk / Pithos.Client.WPF / Utils / EnumerableExtensions.cs
index d76fc09..68b178f 100644 (file)
@@ -4,7 +4,9 @@ using System.Collections.Generic;
 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
@@ -79,30 +81,83 @@ 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]));            
         }
     }
 }