From 63797445be561730e7d117573813ca12c02bc6f1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 5 Jun 2010 00:48:33 +0100
Subject: various refactorings on methods to replicate IAR paths to user
 inventory in order to improve readability

---
 .../Archiver/InventoryArchiveReadRequest.cs        | 208 +++++++++++++--------
 .../Archiver/Tests/InventoryArchiverTests.cs       |   2 +-
 2 files changed, 128 insertions(+), 82 deletions(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 256a886..60d1720 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -97,9 +97,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
             int successfulAssetRestores = 0;
             int failedAssetRestores = 0;
             int successfulItemRestores = 0;
-            List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>();
+            
+            List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>();
            
-            //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath);
             InventoryFolderBase rootDestinationFolder 
                 = InventoryArchiveUtils.FindFolderByPath(
                     m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
@@ -109,14 +109,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                 // Possibly provide an option later on to automatically create this folder if it does not exist
                 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);
 
-                return nodesLoaded;
+                return loadedNodes;
             }
 
             archive = new TarArchiveReader(m_loadStream);
 
             // In order to load identically named folders, we need to keep track of the folders that we have already
-            // created
-            Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
+            // resolved
+            Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>();
 
             byte[] data;
             TarArchiveReader.TarEntryType entryType;
@@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                         
                         InventoryFolderBase foundFolder 
                             = ReplicateArchivePathToUserInventory(
-                                filePath, rootDestinationFolder, foldersCreated, nodesLoaded);
+                                filePath, rootDestinationFolder, resolvedFolders, loadedNodes);
     
                         if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
                         {
@@ -160,7 +160,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                                 // If we're loading an item directly into the given destination folder then we need to record
                                 // it separately from any loaded root folders
                                 if (rootDestinationFolder == foundFolder)
-                                    nodesLoaded.Add(item);
+                                    loadedNodes.Add(item);
                             }
                         }
                     }
@@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                 successfulAssetRestores, failedAssetRestores);
             m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
 
-            return nodesLoaded;
+            return loadedNodes;
         }
 
         public void Close()
@@ -190,45 +190,118 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
         /// </summary>
         /// <param name="archivePath">The item archive path to replicate</param>
         /// <param name="rootDestinationFolder">The root folder for the inventory load</param>
-        /// <param name="foldersCreated">
-        /// The folders created so far.  This method will add more folders if necessary
+        /// <param name="resolvedFolders">
+        /// The folders that we have resolved so far for a given archive path.  
+        /// This method will add more folders if necessary
         /// </param>
-        /// <param name="nodesLoaded">
-        /// Track the inventory nodes created.  This is distinct from the folders created since for a particular folder
-        /// chain, only the root node needs to be recorded
+        /// <param name="loadedNodes">
+        /// Track the inventory nodes created.
         /// </param>
         /// <returns>The last user inventory folder created or found for the archive path</returns>
         public InventoryFolderBase ReplicateArchivePathToUserInventory(
             string archivePath, 
             InventoryFolderBase rootDestFolder, 
-            Dictionary <string, InventoryFolderBase> foldersCreated,
-            List<InventoryNodeBase> nodesLoaded)
+            Dictionary <string, InventoryFolderBase> resolvedFolders,
+            List<InventoryNodeBase> loadedNodes)
         {
             string originalArchivePath = archivePath;
 
 //            m_log.DebugFormat(
 //                "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
+                        
+            InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref archivePath, resolvedFolders);
+            
+//            m_log.DebugFormat(
+//                "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", 
+//                originalArchivePath, archivePath);
+            
+            string archivePathSectionToCreate = originalArchivePath.Substring(archivePath.Length);
+            CreateFoldersForPath(destFolder, archivePathSectionToCreate, resolvedFolders, loadedNodes);
+            
+            return destFolder;
+            
+            /*
+            string[] rawFolders = filePath.Split(new char[] { '/' });
+
+            // Find the folders that do exist along the path given
+            int i = 0;
+            bool noFolder = false;
+            InventoryFolderImpl foundFolder = rootDestinationFolder;
+            while (!noFolder && i < rawFolders.Length)
+            {
+                InventoryFolderImpl folder = foundFolder.FindFolderByPath(rawFolders[i]);
+                if (null != folder)
+                {
+                    m_log.DebugFormat("[INVENTORY ARCHIVER]: Found folder {0}", folder.Name);
+                    foundFolder = folder;
+                    i++;
+                }
+                else
+                {
+                    noFolder = true;
+                }
+            }
+
+            // Create any folders that did not previously exist
+            while (i < rawFolders.Length)
+            {
+                m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawFolders[i]);
+
+                UUID newFolderId = UUID.Random();
+                m_userInfo.CreateFolder(
+                    rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID);
+                foundFolder = foundFolder.GetChildFolder(newFolderId);
+            }
+            */
+        }
+
+        /// <summary>
+        /// Resolve a destination folder
+        /// </summary>
+        /// 
+        /// We require here a root destination folder (usually the root of the user's inventory) and the archive
+        /// path.  We also pass in a list of previously resolved folders in case we've found this one previously.
+        /// 
+        /// <param name="archivePath">
+        /// The item archive path to resolve.  The portion of the path passed back is that
+        /// which corresponds to the resolved desintation folder.
+        /// <param name="rootDestinationFolder">
+        /// The root folder for the inventory load
+        /// </param>
+        /// <param name="resolvedFolders">
+        /// The folders that we have resolved so far for a given archive path.  
+        /// </param>
+        /// <returns>
+        /// The folder in the user's inventory that matches best the archive path given.  If no such folder was found
+        /// then the passed in root destination folder is returned.
+        /// </returns>        
+        protected InventoryFolderBase ResolveDestinationFolder(
+            InventoryFolderBase rootDestFolder,                                                             
+            ref string archivePath,             
+            Dictionary <string, InventoryFolderBase> resolvedFolders)
+        {
+            string originalArchivePath = archivePath;
 
             InventoryFolderBase destFolder = null;
 
-            // XXX: Nasty way of dealing with a path that has no directory component
             if (archivePath.Length > 0)
             {
                 while (null == destFolder && archivePath.Length > 0)
                 {
-                    if (foldersCreated.ContainsKey(archivePath))
+                    if (resolvedFolders.ContainsKey(archivePath))
                     {
 //                        m_log.DebugFormat(
 //                            "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
-                        destFolder = foldersCreated[archivePath];
+                        destFolder = resolvedFolders[archivePath];
                     }
                     else
                     {
-                        // Don't include the last slash
+                        // Don't include the last slash so find the penultimate one
                         int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
 
                         if (penultimateSlashIndex >= 0)
                         {
+                            // Remove the last section of path so that we can see if we've already resolved the parent
                             archivePath = archivePath.Remove(penultimateSlashIndex + 1);
                         }
                         else
@@ -242,19 +315,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                     }
                 }
             }
-            else
-            {
+            
+            if (null == destFolder)
                 destFolder = rootDestFolder;
-            }
-
-            string archivePathSectionToCreate = originalArchivePath.Substring(archivePath.Length);
-            string[] rawDirsToCreate
-                = archivePathSectionToCreate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+            
+            return destFolder;
+        }
+        
+        /// <summary>
+        /// Create a set of folders for the given path.
+        /// </summary>
+        /// <param name="destFolder">
+        /// The root folder from which the creation will take place.
+        /// </param>
+        /// <param name="path">
+        /// The path to create
+        /// </param>
+        /// <param name="resolvedFolders">
+        /// The folders that we have resolved so far for a given archive path.
+        /// </param>
+        /// <param name="loadedNodes">
+        /// Track the inventory nodes created.
+        /// </param>
+        protected void CreateFoldersForPath(
+            InventoryFolderBase destFolder, string path, Dictionary <string, InventoryFolderBase> resolvedFolders, 
+            List<InventoryNodeBase> loadedNodes)
+        {
+            string pathCreated = "";
+            string[] rawDirsToCreate = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
             int i = 0;
 
             while (i < rawDirsToCreate.Length)
             {
-                m_log.DebugFormat("[INVENTORY ARCHIVER]: Loading archived folder {0}", rawDirsToCreate[i]);
+//                m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]);
 
                 int identicalNameIdentifierIndex
                     = rawDirsToCreate[i].LastIndexOf(
@@ -279,66 +372,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                         newFolderId, newFolderName, m_userInfo.PrincipalID, 
                         (short)AssetType.Unknown, destFolder.ID, 1);
                 m_scene.InventoryService.AddFolder(destFolder);
-                
-//                UUID newFolderId = UUID.Random();
-//                m_scene.InventoryService.AddFolder(
-//                m_userInfo.CreateFolder(
-//                    folderName, newFolderId, (ushort)AssetType.Folder, foundFolder.ID);
-
-//                m_log.DebugFormat("[INVENTORY ARCHIVER]: Retrieving newly created folder {0}", folderName);
-//                foundFolder = foundFolder.GetChildFolder(newFolderId);
-//                m_log.DebugFormat(
-//                    "[INVENTORY ARCHIVER]: Retrieved newly created folder {0} with ID {1}", 
-//                    foundFolder.Name, foundFolder.ID);
 
                 // Record that we have now created this folder
-                archivePath += rawDirsToCreate[i] + "/";
-                m_log.DebugFormat("[INVENTORY ARCHIVER]: Loaded archive path {0}", archivePath);
-                foldersCreated[archivePath] = destFolder;
+                pathCreated += rawDirsToCreate[i] + "/";
+                m_log.DebugFormat("[INVENTORY ARCHIVER]: Created folder {0} from IAR", pathCreated);
+                resolvedFolders[pathCreated] = destFolder;
 
                 if (0 == i)
-                    nodesLoaded.Add(destFolder);
+                    loadedNodes.Add(destFolder);
 
                 i++;
-            }
-            
-            return destFolder;
-            
-            /*
-            string[] rawFolders = filePath.Split(new char[] { '/' });
-
-            // Find the folders that do exist along the path given
-            int i = 0;
-            bool noFolder = false;
-            InventoryFolderImpl foundFolder = rootDestinationFolder;
-            while (!noFolder && i < rawFolders.Length)
-            {
-                InventoryFolderImpl folder = foundFolder.FindFolderByPath(rawFolders[i]);
-                if (null != folder)
-                {
-                    m_log.DebugFormat("[INVENTORY ARCHIVER]: Found folder {0}", folder.Name);
-                    foundFolder = folder;
-                    i++;
-                }
-                else
-                {
-                    noFolder = true;
-                }
-            }
-
-            // Create any folders that did not previously exist
-            while (i < rawFolders.Length)
-            {
-                m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawFolders[i]);
-
-                UUID newFolderId = UUID.Random();
-                m_userInfo.CreateFolder(
-                    rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID);
-                foundFolder = foundFolder.GetChildFolder(newFolderId);
-            }
-            */
+            }            
         }
-
+        
         /// <summary>
         /// Load an item from the archive
         /// </summary>
@@ -429,4 +475,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index cb6bf76..59cd386 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -279,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
         public void TestIarV0_1WithEscapedChars()
         {
             TestHelper.InMethod();
-//            log4net.Config.XmlConfigurator.Configure();
+            log4net.Config.XmlConfigurator.Configure();
 
             string itemName = "You & you are a mean/man/";
             string humanEscapedItemName = @"You & you are a mean\/man\/";
-- 
cgit v1.1