diff options
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | 208 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | 2 |
2 files changed, 128 insertions, 82 deletions
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 | |||
97 | int successfulAssetRestores = 0; | 97 | int successfulAssetRestores = 0; |
98 | int failedAssetRestores = 0; | 98 | int failedAssetRestores = 0; |
99 | int successfulItemRestores = 0; | 99 | int successfulItemRestores = 0; |
100 | List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>(); | 100 | |
101 | List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>(); | ||
101 | 102 | ||
102 | //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); | ||
103 | InventoryFolderBase rootDestinationFolder | 103 | InventoryFolderBase rootDestinationFolder |
104 | = InventoryArchiveUtils.FindFolderByPath( | 104 | = InventoryArchiveUtils.FindFolderByPath( |
105 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); | 105 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); |
@@ -109,14 +109,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
109 | // Possibly provide an option later on to automatically create this folder if it does not exist | 109 | // Possibly provide an option later on to automatically create this folder if it does not exist |
110 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); | 110 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); |
111 | 111 | ||
112 | return nodesLoaded; | 112 | return loadedNodes; |
113 | } | 113 | } |
114 | 114 | ||
115 | archive = new TarArchiveReader(m_loadStream); | 115 | archive = new TarArchiveReader(m_loadStream); |
116 | 116 | ||
117 | // In order to load identically named folders, we need to keep track of the folders that we have already | 117 | // In order to load identically named folders, we need to keep track of the folders that we have already |
118 | // created | 118 | // resolved |
119 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); | 119 | Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>(); |
120 | 120 | ||
121 | byte[] data; | 121 | byte[] data; |
122 | TarArchiveReader.TarEntryType entryType; | 122 | TarArchiveReader.TarEntryType entryType; |
@@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
147 | 147 | ||
148 | InventoryFolderBase foundFolder | 148 | InventoryFolderBase foundFolder |
149 | = ReplicateArchivePathToUserInventory( | 149 | = ReplicateArchivePathToUserInventory( |
150 | filePath, rootDestinationFolder, foldersCreated, nodesLoaded); | 150 | filePath, rootDestinationFolder, resolvedFolders, loadedNodes); |
151 | 151 | ||
152 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) | 152 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) |
153 | { | 153 | { |
@@ -160,7 +160,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
160 | // If we're loading an item directly into the given destination folder then we need to record | 160 | // If we're loading an item directly into the given destination folder then we need to record |
161 | // it separately from any loaded root folders | 161 | // it separately from any loaded root folders |
162 | if (rootDestinationFolder == foundFolder) | 162 | if (rootDestinationFolder == foundFolder) |
163 | nodesLoaded.Add(item); | 163 | loadedNodes.Add(item); |
164 | } | 164 | } |
165 | } | 165 | } |
166 | } | 166 | } |
@@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
176 | successfulAssetRestores, failedAssetRestores); | 176 | successfulAssetRestores, failedAssetRestores); |
177 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); | 177 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); |
178 | 178 | ||
179 | return nodesLoaded; | 179 | return loadedNodes; |
180 | } | 180 | } |
181 | 181 | ||
182 | public void Close() | 182 | public void Close() |
@@ -190,45 +190,118 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
190 | /// </summary> | 190 | /// </summary> |
191 | /// <param name="archivePath">The item archive path to replicate</param> | 191 | /// <param name="archivePath">The item archive path to replicate</param> |
192 | /// <param name="rootDestinationFolder">The root folder for the inventory load</param> | 192 | /// <param name="rootDestinationFolder">The root folder for the inventory load</param> |
193 | /// <param name="foldersCreated"> | 193 | /// <param name="resolvedFolders"> |
194 | /// The folders created so far. This method will add more folders if necessary | 194 | /// The folders that we have resolved so far for a given archive path. |
195 | /// This method will add more folders if necessary | ||
195 | /// </param> | 196 | /// </param> |
196 | /// <param name="nodesLoaded"> | 197 | /// <param name="loadedNodes"> |
197 | /// Track the inventory nodes created. This is distinct from the folders created since for a particular folder | 198 | /// Track the inventory nodes created. |
198 | /// chain, only the root node needs to be recorded | ||
199 | /// </param> | 199 | /// </param> |
200 | /// <returns>The last user inventory folder created or found for the archive path</returns> | 200 | /// <returns>The last user inventory folder created or found for the archive path</returns> |
201 | public InventoryFolderBase ReplicateArchivePathToUserInventory( | 201 | public InventoryFolderBase ReplicateArchivePathToUserInventory( |
202 | string archivePath, | 202 | string archivePath, |
203 | InventoryFolderBase rootDestFolder, | 203 | InventoryFolderBase rootDestFolder, |
204 | Dictionary <string, InventoryFolderBase> foldersCreated, | 204 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
205 | List<InventoryNodeBase> nodesLoaded) | 205 | List<InventoryNodeBase> loadedNodes) |
206 | { | 206 | { |
207 | string originalArchivePath = archivePath; | 207 | string originalArchivePath = archivePath; |
208 | 208 | ||
209 | // m_log.DebugFormat( | 209 | // m_log.DebugFormat( |
210 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); | 210 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); |
211 | |||
212 | InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref archivePath, resolvedFolders); | ||
213 | |||
214 | // m_log.DebugFormat( | ||
215 | // "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", | ||
216 | // originalArchivePath, archivePath); | ||
217 | |||
218 | string archivePathSectionToCreate = originalArchivePath.Substring(archivePath.Length); | ||
219 | CreateFoldersForPath(destFolder, archivePathSectionToCreate, resolvedFolders, loadedNodes); | ||
220 | |||
221 | return destFolder; | ||
222 | |||
223 | /* | ||
224 | string[] rawFolders = filePath.Split(new char[] { '/' }); | ||
225 | |||
226 | // Find the folders that do exist along the path given | ||
227 | int i = 0; | ||
228 | bool noFolder = false; | ||
229 | InventoryFolderImpl foundFolder = rootDestinationFolder; | ||
230 | while (!noFolder && i < rawFolders.Length) | ||
231 | { | ||
232 | InventoryFolderImpl folder = foundFolder.FindFolderByPath(rawFolders[i]); | ||
233 | if (null != folder) | ||
234 | { | ||
235 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Found folder {0}", folder.Name); | ||
236 | foundFolder = folder; | ||
237 | i++; | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | noFolder = true; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | // Create any folders that did not previously exist | ||
246 | while (i < rawFolders.Length) | ||
247 | { | ||
248 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawFolders[i]); | ||
249 | |||
250 | UUID newFolderId = UUID.Random(); | ||
251 | m_userInfo.CreateFolder( | ||
252 | rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID); | ||
253 | foundFolder = foundFolder.GetChildFolder(newFolderId); | ||
254 | } | ||
255 | */ | ||
256 | } | ||
257 | |||
258 | /// <summary> | ||
259 | /// Resolve a destination folder | ||
260 | /// </summary> | ||
261 | /// | ||
262 | /// We require here a root destination folder (usually the root of the user's inventory) and the archive | ||
263 | /// path. We also pass in a list of previously resolved folders in case we've found this one previously. | ||
264 | /// | ||
265 | /// <param name="archivePath"> | ||
266 | /// The item archive path to resolve. The portion of the path passed back is that | ||
267 | /// which corresponds to the resolved desintation folder. | ||
268 | /// <param name="rootDestinationFolder"> | ||
269 | /// The root folder for the inventory load | ||
270 | /// </param> | ||
271 | /// <param name="resolvedFolders"> | ||
272 | /// The folders that we have resolved so far for a given archive path. | ||
273 | /// </param> | ||
274 | /// <returns> | ||
275 | /// The folder in the user's inventory that matches best the archive path given. If no such folder was found | ||
276 | /// then the passed in root destination folder is returned. | ||
277 | /// </returns> | ||
278 | protected InventoryFolderBase ResolveDestinationFolder( | ||
279 | InventoryFolderBase rootDestFolder, | ||
280 | ref string archivePath, | ||
281 | Dictionary <string, InventoryFolderBase> resolvedFolders) | ||
282 | { | ||
283 | string originalArchivePath = archivePath; | ||
211 | 284 | ||
212 | InventoryFolderBase destFolder = null; | 285 | InventoryFolderBase destFolder = null; |
213 | 286 | ||
214 | // XXX: Nasty way of dealing with a path that has no directory component | ||
215 | if (archivePath.Length > 0) | 287 | if (archivePath.Length > 0) |
216 | { | 288 | { |
217 | while (null == destFolder && archivePath.Length > 0) | 289 | while (null == destFolder && archivePath.Length > 0) |
218 | { | 290 | { |
219 | if (foldersCreated.ContainsKey(archivePath)) | 291 | if (resolvedFolders.ContainsKey(archivePath)) |
220 | { | 292 | { |
221 | // m_log.DebugFormat( | 293 | // m_log.DebugFormat( |
222 | // "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); | 294 | // "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); |
223 | destFolder = foldersCreated[archivePath]; | 295 | destFolder = resolvedFolders[archivePath]; |
224 | } | 296 | } |
225 | else | 297 | else |
226 | { | 298 | { |
227 | // Don't include the last slash | 299 | // Don't include the last slash so find the penultimate one |
228 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); | 300 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); |
229 | 301 | ||
230 | if (penultimateSlashIndex >= 0) | 302 | if (penultimateSlashIndex >= 0) |
231 | { | 303 | { |
304 | // Remove the last section of path so that we can see if we've already resolved the parent | ||
232 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); | 305 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); |
233 | } | 306 | } |
234 | else | 307 | else |
@@ -242,19 +315,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
242 | } | 315 | } |
243 | } | 316 | } |
244 | } | 317 | } |
245 | else | 318 | |
246 | { | 319 | if (null == destFolder) |
247 | destFolder = rootDestFolder; | 320 | destFolder = rootDestFolder; |
248 | } | 321 | |
249 | 322 | return destFolder; | |
250 | string archivePathSectionToCreate = originalArchivePath.Substring(archivePath.Length); | 323 | } |
251 | string[] rawDirsToCreate | 324 | |
252 | = archivePathSectionToCreate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | 325 | /// <summary> |
326 | /// Create a set of folders for the given path. | ||
327 | /// </summary> | ||
328 | /// <param name="destFolder"> | ||
329 | /// The root folder from which the creation will take place. | ||
330 | /// </param> | ||
331 | /// <param name="path"> | ||
332 | /// The path to create | ||
333 | /// </param> | ||
334 | /// <param name="resolvedFolders"> | ||
335 | /// The folders that we have resolved so far for a given archive path. | ||
336 | /// </param> | ||
337 | /// <param name="loadedNodes"> | ||
338 | /// Track the inventory nodes created. | ||
339 | /// </param> | ||
340 | protected void CreateFoldersForPath( | ||
341 | InventoryFolderBase destFolder, string path, Dictionary <string, InventoryFolderBase> resolvedFolders, | ||
342 | List<InventoryNodeBase> loadedNodes) | ||
343 | { | ||
344 | string pathCreated = ""; | ||
345 | string[] rawDirsToCreate = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | ||
253 | int i = 0; | 346 | int i = 0; |
254 | 347 | ||
255 | while (i < rawDirsToCreate.Length) | 348 | while (i < rawDirsToCreate.Length) |
256 | { | 349 | { |
257 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Loading archived folder {0}", rawDirsToCreate[i]); | 350 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]); |
258 | 351 | ||
259 | int identicalNameIdentifierIndex | 352 | int identicalNameIdentifierIndex |
260 | = rawDirsToCreate[i].LastIndexOf( | 353 | = rawDirsToCreate[i].LastIndexOf( |
@@ -279,66 +372,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
279 | newFolderId, newFolderName, m_userInfo.PrincipalID, | 372 | newFolderId, newFolderName, m_userInfo.PrincipalID, |
280 | (short)AssetType.Unknown, destFolder.ID, 1); | 373 | (short)AssetType.Unknown, destFolder.ID, 1); |
281 | m_scene.InventoryService.AddFolder(destFolder); | 374 | m_scene.InventoryService.AddFolder(destFolder); |
282 | |||
283 | // UUID newFolderId = UUID.Random(); | ||
284 | // m_scene.InventoryService.AddFolder( | ||
285 | // m_userInfo.CreateFolder( | ||
286 | // folderName, newFolderId, (ushort)AssetType.Folder, foundFolder.ID); | ||
287 | |||
288 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Retrieving newly created folder {0}", folderName); | ||
289 | // foundFolder = foundFolder.GetChildFolder(newFolderId); | ||
290 | // m_log.DebugFormat( | ||
291 | // "[INVENTORY ARCHIVER]: Retrieved newly created folder {0} with ID {1}", | ||
292 | // foundFolder.Name, foundFolder.ID); | ||
293 | 375 | ||
294 | // Record that we have now created this folder | 376 | // Record that we have now created this folder |
295 | archivePath += rawDirsToCreate[i] + "/"; | 377 | pathCreated += rawDirsToCreate[i] + "/"; |
296 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Loaded archive path {0}", archivePath); | 378 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Created folder {0} from IAR", pathCreated); |
297 | foldersCreated[archivePath] = destFolder; | 379 | resolvedFolders[pathCreated] = destFolder; |
298 | 380 | ||
299 | if (0 == i) | 381 | if (0 == i) |
300 | nodesLoaded.Add(destFolder); | 382 | loadedNodes.Add(destFolder); |
301 | 383 | ||
302 | i++; | 384 | i++; |
303 | } | 385 | } |
304 | |||
305 | return destFolder; | ||
306 | |||
307 | /* | ||
308 | string[] rawFolders = filePath.Split(new char[] { '/' }); | ||
309 | |||
310 | // Find the folders that do exist along the path given | ||
311 | int i = 0; | ||
312 | bool noFolder = false; | ||
313 | InventoryFolderImpl foundFolder = rootDestinationFolder; | ||
314 | while (!noFolder && i < rawFolders.Length) | ||
315 | { | ||
316 | InventoryFolderImpl folder = foundFolder.FindFolderByPath(rawFolders[i]); | ||
317 | if (null != folder) | ||
318 | { | ||
319 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Found folder {0}", folder.Name); | ||
320 | foundFolder = folder; | ||
321 | i++; | ||
322 | } | ||
323 | else | ||
324 | { | ||
325 | noFolder = true; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | // Create any folders that did not previously exist | ||
330 | while (i < rawFolders.Length) | ||
331 | { | ||
332 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawFolders[i]); | ||
333 | |||
334 | UUID newFolderId = UUID.Random(); | ||
335 | m_userInfo.CreateFolder( | ||
336 | rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID); | ||
337 | foundFolder = foundFolder.GetChildFolder(newFolderId); | ||
338 | } | ||
339 | */ | ||
340 | } | 386 | } |
341 | 387 | ||
342 | /// <summary> | 388 | /// <summary> |
343 | /// Load an item from the archive | 389 | /// Load an item from the archive |
344 | /// </summary> | 390 | /// </summary> |
@@ -429,4 +475,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
429 | } | 475 | } |
430 | } | 476 | } |
431 | } | 477 | } |
432 | } | 478 | } \ 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 | |||
279 | public void TestIarV0_1WithEscapedChars() | 279 | public void TestIarV0_1WithEscapedChars() |
280 | { | 280 | { |
281 | TestHelper.InMethod(); | 281 | TestHelper.InMethod(); |
282 | // log4net.Config.XmlConfigurator.Configure(); | 282 | log4net.Config.XmlConfigurator.Configure(); |
283 | 283 | ||
284 | string itemName = "You & you are a mean/man/"; | 284 | string itemName = "You & you are a mean/man/"; |
285 | string humanEscapedItemName = @"You & you are a mean\/man\/"; | 285 | string humanEscapedItemName = @"You & you are a mean\/man\/"; |