From a62b906a7b77340c61c4d3b084c3d950cf5172ba Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Thu, 31 Jul 2008 17:32:13 +0000 Subject: * allow inventory folders to be located by path * first pass method impl --- .../Communications/Cache/CachedUserInfo.cs | 6 +-- .../Communications/Cache/InventoryFolderImpl.cs | 58 +++++++++++++++++++--- OpenSim/Region/Application/OpenSimBase.cs | 43 +++++++++++++++- 3 files changed, 96 insertions(+), 11 deletions(-) diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs index d6e1715..025b934 100644 --- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs @@ -64,7 +64,7 @@ namespace OpenSim.Framework.Communications.Cache private readonly UserProfileData m_userProfile; /// - /// Has we received the user's inventory from the inventory service? + /// Have we received the user's inventory from the inventory service? /// public bool HasReceivedInventory { get { return m_hasReceivedInventory; } } private bool m_hasReceivedInventory; @@ -85,9 +85,9 @@ namespace OpenSim.Framework.Communications.Cache /// private IDictionary> pendingCategorizationFolders = new Dictionary>(); - - private LLUUID m_session_id = LLUUID.Zero; + public LLUUID SessionID { get { return m_session_id; } } + private LLUUID m_session_id = LLUUID.Zero; /// /// Constructor diff --git a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs b/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs index 0fbc427..b1fdf76 100644 --- a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs +++ b/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; using libsecondlife; //using System.Reflection; @@ -36,12 +37,22 @@ namespace OpenSim.Framework.Communications.Cache public class InventoryFolderImpl : InventoryFolderBase { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public static readonly string PATH_DELIMITER = "/"; - // Fields + /// + /// Items that are contained in this folder + /// public Dictionary Items = new Dictionary(); + + /// + /// Child folders that are contained in this folder + /// public Dictionary SubFolders = new Dictionary(); - // Accessors + /// + /// The number of child folders + /// public int SubFoldersCount { get { return SubFolders.Count; } @@ -177,9 +188,7 @@ namespace OpenSim.Framework.Communications.Cache public InventoryFolderImpl FindFolder(LLUUID folderID) { if (folderID == ID) - { return this; - } lock (SubFolders) { @@ -188,14 +197,51 @@ namespace OpenSim.Framework.Communications.Cache InventoryFolderImpl returnFolder = folder.FindFolder(folderID); if (returnFolder != null) - { return returnFolder; - } } } return null; } + + /// + /// Find a folder given a PATH_DELIMITOR delimited path. + /// + /// This method does not handle paths that contain multiple delimitors + /// + /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some + /// XPath like expression + /// + /// FIXME: Delimitors which occur in names themselves are not currently escapable. + /// + /// + /// The path to the required folder. It this is empty then this folder itself is returned. + /// If a folder for the given path is not found, then null is returned. + /// + /// + public InventoryFolderImpl FindFolderByPath(string path) + { + if (path == string.Empty) + return this; + + int delimitorIndex = path.IndexOf(PATH_DELIMITER); + string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); + + lock (SubFolders) + { + foreach (InventoryFolderImpl folder in SubFolders.Values) + { + if (folder.Name == components[0]) + if (components.Length > 1) + return folder.FindFolderByPath(components[1]); + else + return folder; + } + } + + // We didn't find a folder with the given name + return null; + } /// /// Return the list of child items in this folder diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 2b3ffd8..0d471d8 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -680,7 +680,7 @@ namespace OpenSim string firstName = cmdparams[0]; string lastName = cmdparams[1]; - //string invPath = cmdparams[2]; + string invPath = cmdparams[2]; //string savePath = (cmdparams.Length > 3 ? cmdparams[3] : DEFAULT_INV_BACKUP_FILENAME); UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(firstName, lastName); @@ -695,7 +695,46 @@ namespace OpenSim { m_log.ErrorFormat("[CONSOLE]: Failed to find user info for {0} {1} {2}", firstName, lastName, userProfile.ID); return; - } + } + + InventoryFolderImpl inventoryFolder = null; + + if (userInfo.HasReceivedInventory) + { + if (invPath == InventoryFolderImpl.PATH_DELIMITER) + { + inventoryFolder = userInfo.RootFolder; + } + else + { + // Eliminate double slashes and any leading / on the path. This might be better done within InventoryFolderImpl + // itself (possibly at a small loss in efficiency). + string[] components + = invPath.Split(new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); + invPath = String.Empty; + foreach (string c in components) + { + invPath += c + InventoryFolderImpl.PATH_DELIMITER; + } + + inventoryFolder = userInfo.RootFolder.FindFolderByPath(invPath); + } + } + else + { + m_log.ErrorFormat("[CONSOLE]: Have not yet received inventory info for user {0} {1} {2}", firstName, lastName, userProfile.ID); + return; + } + + if (null == inventoryFolder) + { + m_log.ErrorFormat("[CONSOLE]: Could not find folder with path {0}", invPath); + return; + } + else + { + m_log.InfoFormat("[CONSOLE]: Found folder {0} {1} at {2}", inventoryFolder.Name, inventoryFolder.ID, invPath); + } } /// -- cgit v1.1