From b52ac542ade6af9ad404dcebf68be3bef769b0e1 Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Wed, 4 Mar 2009 20:31:03 +0000
Subject: * Add the abilty to load and save iar item nodes where folders have
identical names
---
.../Archiver/InventoryArchiveConstants.cs | 5 ++
.../Archiver/InventoryArchiveReadRequest.cs | 91 ++++++++++++++++++----
.../Archiver/InventoryArchiveWriteRequest.cs | 55 +++++++++----
.../Archiver/Tests/InventoryArchiverTests.cs | 12 ++-
4 files changed, 132 insertions(+), 31 deletions(-)
(limited to 'OpenSim/Region/CoreModules/Avatar')
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveConstants.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveConstants.cs
index b274af2..e2bce16 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveConstants.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveConstants.cs
@@ -51,6 +51,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
public static readonly string ASSET_EXTENSION_SEPARATOR = "_";
///
+ /// Used to separate components in an inventory node name
+ ///
+ public static readonly string INVENTORY_NODE_NAME_COMPONENT_SEPARATOR = "__";
+
+ ///
/// Extensions used for asset types in the archive
///
public static readonly IDictionary ASSET_TYPE_TO_EXTENSION = new Dictionary();
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index fc63957..4a681bc 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (contents.Equals("")) return null;
- reader.ReadStartElement("InventoryObject");
+ reader.ReadStartElement("InventoryItem");
reader.ReadStartElement("Name");
item.Name = reader.ReadString();
reader.ReadEndElement();
@@ -138,10 +138,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
reader.ReadStartElement("GroupOwned");
item.GroupOwned = Convert.ToBoolean(reader.ReadString());
reader.ReadEndElement();
- //reader.ReadStartElement("ParentFolderID");
- //item.Folder = UUID.Parse(reader.ReadString());
- //reader.ReadEndElement();
- //reader.ReadEndElement();
return item;
}
@@ -187,13 +183,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (null == rootDestinationFolder)
{
- // TODO: Later on, automatically create this folder if it does not exist
+ // 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;
}
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 foldersCreated = new Dictionary();
byte[] data;
TarArchiveReader.TarEntryType entryType;
@@ -222,12 +222,72 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
item.Creator = m_userInfo.UserProfile.ID;
item.Owner = m_userInfo.UserProfile.ID;
- filePath = filePath.Substring(InventoryArchiveConstants.INVENTORY_PATH.Length);
- filePath = filePath.Remove(filePath.LastIndexOf("/"));
+ string fsPath = filePath.Substring(InventoryArchiveConstants.INVENTORY_PATH.Length);
+ fsPath = fsPath.Remove(fsPath.LastIndexOf("/") + 1);
+ string originalFsPath = fsPath;
+
+ m_log.DebugFormat("[INVENTORY ARCHIVER]: Loading to folder {0}", fsPath);
- m_log.DebugFormat("[INVENTORY ARCHIVER]: Loading to file path {0}", filePath);
+ InventoryFolderImpl foundFolder = null;
+ while (null == foundFolder && fsPath.Length > 0)
+ {
+ if (foldersCreated.ContainsKey(fsPath))
+ {
+ m_log.DebugFormat("[INVENTORY ARCHIVER]: Found previously created fs path {0}", fsPath);
+ foundFolder = foldersCreated[fsPath];
+ }
+ else
+ {
+ // Don't include the last slash
+ int penultimateSlashIndex = fsPath.LastIndexOf("/", fsPath.Length - 2);
+
+ if (penultimateSlashIndex >= 0)
+ {
+ fsPath = fsPath.Remove(penultimateSlashIndex + 1);
+ }
+ else
+ {
+ m_log.DebugFormat(
+ "[INVENTORY ARCHIVER]: Found no previously created fs path for {0}",
+ originalFsPath);
+ fsPath = string.Empty;
+ foundFolder = rootDestinationFolder;
+ }
+ }
+ }
- string[] rawFolders = filePath.Split(new char[] { '/' });
+ string fsPathSectionToCreate = originalFsPath.Substring(fsPath.Length);
+ string[] rawDirsToCreate
+ = fsPathSectionToCreate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+ int i = 0;
+
+ while (i < rawDirsToCreate.Length)
+ {
+ m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawDirsToCreate[i]);
+
+ int identicalNameIdentifierIndex
+ = rawDirsToCreate[i].LastIndexOf(
+ InventoryArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
+ string folderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
+
+ UUID newFolderId = UUID.Random();
+ m_userInfo.CreateFolder(
+ folderName, newFolderId, (ushort)AssetType.Folder, foundFolder.ID);
+ foundFolder = foundFolder.GetChildFolder(newFolderId);
+
+ // Record that we have now created this folder
+ fsPath += rawDirsToCreate[i] + "/";
+ m_log.DebugFormat("[INVENTORY ARCHIVER]: Recording creation of fs path {0}", fsPath);
+ foldersCreated[fsPath] = foundFolder;
+
+ if (0 == i)
+ nodesLoaded.Add(foundFolder);
+
+ i++;
+ }
+
+ /*
+ string[] rawFolders = filePath.Split(new char[] { '/' });
// Find the folders that do exist along the path given
int i = 0;
@@ -257,16 +317,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_userInfo.CreateFolder(
rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID);
foundFolder = foundFolder.GetChildFolder(newFolderId);
- }
+ }
+ */
// Reset folder ID to the one in which we want to load it
item.Folder = foundFolder.ID;
-
- //item.Folder = rootDestinationFolder.ID;
m_userInfo.AddItem(item);
successfulItemRestores++;
- nodesLoaded.Add(item);
+
+ // 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);
}
}
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 2b071f0..357ed40 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -106,14 +106,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_module.TriggerInventoryArchiveSaved(succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
}
- protected void saveInvItem(InventoryItemBase inventoryItem, string path)
+ protected void SaveInvItem(InventoryItemBase inventoryItem, string path)
{
string filename = string.Format("{0}{1}_{2}.xml", path, inventoryItem.Name, inventoryItem.ID);
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.Indented;
- writer.WriteStartElement("InventoryObject");
+ writer.WriteStartElement("InventoryItem");
+
writer.WriteStartElement("Name");
writer.WriteString(inventoryItem.Name);
writer.WriteEndElement();
@@ -168,9 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
writer.WriteStartElement("GroupOwned");
writer.WriteString(inventoryItem.GroupOwned.ToString());
writer.WriteEndElement();
- writer.WriteStartElement("ParentFolderID");
- writer.WriteString(inventoryItem.Folder.ToString());
- writer.WriteEndElement();
+
writer.WriteEndElement();
archive.AddFile(filename, sw.ToString());
@@ -178,20 +177,48 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, assetUuids);
}
- protected void saveInvDir(InventoryFolderImpl inventoryFolder, string path)
+ protected void SaveInvDir(InventoryFolderImpl inventoryFolder, string path)
{
- List inventories = inventoryFolder.RequestListOfFolderImpls();
- List items = inventoryFolder.RequestListOfItems();
- string newPath = path + inventoryFolder.Name + InventoryFolderImpl.PATH_DELIMITER;
- archive.AddDir(newPath);
+ path +=
+ string.Format(
+ "{0}{1}{2}/",
+ inventoryFolder.Name,
+ InventoryArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
+ inventoryFolder.ID);
+ archive.AddDir(path);
+
+ List childFolders = inventoryFolder.RequestListOfFolderImpls();
+ List items = inventoryFolder.RequestListOfItems();
+
+ /*
+ Dictionary identicalFolderNames = new Dictionary();
foreach (InventoryFolderImpl folder in inventories)
{
- saveInvDir(folder, newPath);
+
+ if (!identicalFolderNames.ContainsKey(folder.Name))
+ identicalFolderNames[folder.Name] = 0;
+ else
+ identicalFolderNames[folder.Name] = identicalFolderNames[folder.Name]++;
+
+ int folderNameNumber = identicalFolderName[folder.Name];
+
+ SaveInvDir(
+ folder,
+ string.Format(
+ "{0}{1}{2}/",
+ path, InventoryArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, folderNameNumber));
+ }
+ */
+
+ foreach (InventoryFolderImpl childFolder in childFolders)
+ {
+ SaveInvDir(childFolder, path);
}
+
foreach (InventoryItemBase item in items)
{
- saveInvItem(item, newPath);
+ SaveInvItem(item, path);
}
}
@@ -270,7 +297,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
inventoryItem.Name, inventoryItem.ID, m_invPath);
//get and export item info
- saveInvItem(inventoryItem, m_invPath);
+ SaveInvItem(inventoryItem, m_invPath);
}
}
else
@@ -280,7 +307,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
inventoryFolder.Name, inventoryFolder.ID, m_invPath);
//recurse through all dirs getting dirs and files
- saveInvDir(inventoryFolder, InventoryArchiveConstants.INVENTORY_PATH);
+ SaveInvDir(inventoryFolder, InventoryArchiveConstants.INVENTORY_PATH);
}
new AssetsRequest(assetUuids.Keys, m_module.CommsManager.AssetCache, ReceivedAllAssets).Execute();
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index cb613f7..5cc0340 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -124,15 +124,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
MemoryStream archiveReadStream = new MemoryStream(archive);
TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
+ InventoryFolderImpl objectsFolder = userInfo.RootFolder.FindFolderByPath("Objects");
+
//bool gotControlFile = false;
bool gotObject1File = false;
//bool gotObject2File = false;
string expectedObject1FilePath = string.Format(
- "{0}{1}{2}_{3}.xml",
+ "{0}{1}/{2}_{3}.xml",
InventoryArchiveConstants.INVENTORY_PATH,
- "Objects/",
+ string.Format(
+ "Objects{0}{1}", InventoryArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, objectsFolder.ID),
item1.Name,
item1Id);
+
/*
string expectedObject2FileName = string.Format(
"{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
@@ -146,6 +150,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
while (tar.ReadEntry(out filePath, out tarEntryType) != null)
{
+ Console.WriteLine("Got {0}", filePath);
+
/*
if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
{
@@ -153,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
}
*/
if (filePath.StartsWith(InventoryArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
- {
+ {
//string fileName = filePath.Remove(0, "Objects/".Length);
//if (fileName.StartsWith(part1.Name))
--
cgit v1.1