diff options
author | Justin Clark-Casey (justincc) | 2010-06-30 00:10:44 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2010-06-30 00:10:44 +0100 |
commit | 5925aac859ee493fd7f6b10026c84a6a22626c79 (patch) | |
tree | f7584dad5efc48c29ab51ef433a014900df98a29 /OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |
parent | Revert "stop exceptions in setting and getting state from propogating since t... (diff) | |
download | opensim-SC_OLD-5925aac859ee493fd7f6b10026c84a6a22626c79.zip opensim-SC_OLD-5925aac859ee493fd7f6b10026c84a6a22626c79.tar.gz opensim-SC_OLD-5925aac859ee493fd7f6b10026c84a6a22626c79.tar.bz2 opensim-SC_OLD-5925aac859ee493fd7f6b10026c84a6a22626c79.tar.xz |
Add --merge switch to load iar.
When this switch is used, iar folders are merged with existing same-name user inventory folders.
This makes it a little easier to back and restore entire individual user inventories, among other things
Added unit test to check behaviour
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 9996074..f130b3e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -54,6 +54,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
54 | 54 | ||
55 | private UserAccount m_userInfo; | 55 | private UserAccount m_userInfo; |
56 | private string m_invPath; | 56 | private string m_invPath; |
57 | |||
58 | /// <summary> | ||
59 | /// Do we want to merge this load with existing inventory? | ||
60 | /// </summary> | ||
61 | protected bool m_merge; | ||
57 | 62 | ||
58 | /// <value> | 63 | /// <value> |
59 | /// We only use this to request modules | 64 | /// We only use this to request modules |
@@ -66,19 +71,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
66 | private Stream m_loadStream; | 71 | private Stream m_loadStream; |
67 | 72 | ||
68 | public InventoryArchiveReadRequest( | 73 | public InventoryArchiveReadRequest( |
69 | Scene scene, UserAccount userInfo, string invPath, string loadPath) | 74 | Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) |
70 | : this( | 75 | : this( |
71 | scene, | 76 | scene, |
72 | userInfo, | 77 | userInfo, |
73 | invPath, | 78 | invPath, |
74 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress)) | 79 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), |
80 | merge) | ||
75 | { | 81 | { |
76 | } | 82 | } |
77 | 83 | ||
78 | public InventoryArchiveReadRequest( | 84 | public InventoryArchiveReadRequest( |
79 | Scene scene, UserAccount userInfo, string invPath, Stream loadStream) | 85 | Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge) |
80 | { | 86 | { |
81 | m_scene = scene; | 87 | m_scene = scene; |
88 | m_merge = merge; | ||
82 | m_userInfo = userInfo; | 89 | m_userInfo = userInfo; |
83 | m_invPath = invPath; | 90 | m_invPath = invPath; |
84 | m_loadStream = loadStream; | 91 | m_loadStream = loadStream; |
@@ -91,14 +98,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
91 | /// A list of the inventory nodes loaded. If folders were loaded then only the root folders are | 98 | /// A list of the inventory nodes loaded. If folders were loaded then only the root folders are |
92 | /// returned | 99 | /// returned |
93 | /// </returns> | 100 | /// </returns> |
94 | public List<InventoryNodeBase> Execute() | 101 | public HashSet<InventoryNodeBase> Execute() |
95 | { | 102 | { |
96 | string filePath = "ERROR"; | 103 | string filePath = "ERROR"; |
97 | int successfulAssetRestores = 0; | 104 | int successfulAssetRestores = 0; |
98 | int failedAssetRestores = 0; | 105 | int failedAssetRestores = 0; |
99 | int successfulItemRestores = 0; | 106 | int successfulItemRestores = 0; |
100 | 107 | ||
101 | List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>(); | 108 | HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>(); |
102 | 109 | ||
103 | List<InventoryFolderBase> folderCandidates | 110 | List<InventoryFolderBase> folderCandidates |
104 | = InventoryArchiveUtils.FindFolderByPath( | 111 | = InventoryArchiveUtils.FindFolderByPath( |
@@ -158,9 +165,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
158 | { | 165 | { |
159 | successfulItemRestores++; | 166 | successfulItemRestores++; |
160 | 167 | ||
161 | // If we're loading an item directly into the given destination folder then we need to record | 168 | // If we aren't loading the folder containing the item then well need to update the |
162 | // it separately from any loaded root folders | 169 | // viewer separately for that item. |
163 | if (rootDestinationFolder == foundFolder) | 170 | if (!loadedNodes.Contains(foundFolder)) |
164 | loadedNodes.Add(item); | 171 | loadedNodes.Add(item); |
165 | } | 172 | } |
166 | } | 173 | } |
@@ -203,14 +210,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
203 | string iarPath, | 210 | string iarPath, |
204 | InventoryFolderBase rootDestFolder, | 211 | InventoryFolderBase rootDestFolder, |
205 | Dictionary <string, InventoryFolderBase> resolvedFolders, | 212 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
206 | List<InventoryNodeBase> loadedNodes) | 213 | HashSet<InventoryNodeBase> loadedNodes) |
207 | { | 214 | { |
208 | string iarPathExisting = iarPath; | 215 | string iarPathExisting = iarPath; |
209 | 216 | ||
210 | // m_log.DebugFormat( | 217 | // m_log.DebugFormat( |
211 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); | 218 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); |
212 | 219 | ||
213 | InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); | 220 | InventoryFolderBase destFolder |
221 | = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); | ||
214 | 222 | ||
215 | m_log.DebugFormat( | 223 | m_log.DebugFormat( |
216 | "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", | 224 | "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", |
@@ -249,46 +257,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
249 | { | 257 | { |
250 | string originalArchivePath = archivePath; | 258 | string originalArchivePath = archivePath; |
251 | 259 | ||
252 | InventoryFolderBase destFolder = null; | 260 | while (archivePath.Length > 0) |
253 | |||
254 | if (archivePath.Length > 0) | ||
255 | { | 261 | { |
256 | while (null == destFolder && archivePath.Length > 0) | 262 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); |
263 | |||
264 | if (resolvedFolders.ContainsKey(archivePath)) | ||
257 | { | 265 | { |
258 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); | 266 | m_log.DebugFormat( |
267 | "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); | ||
268 | return resolvedFolders[archivePath]; | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | if (m_merge) | ||
273 | { | ||
274 | // TODO: Using m_invPath is totally wrong - what we need to do is strip the uuid from the | ||
275 | // iar name and try to find that instead. | ||
276 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); | ||
277 | List<InventoryFolderBase> folderCandidates | ||
278 | = InventoryArchiveUtils.FindFolderByPath( | ||
279 | m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); | ||
280 | |||
281 | if (folderCandidates.Count != 0) | ||
282 | { | ||
283 | InventoryFolderBase destFolder = folderCandidates[0]; | ||
284 | resolvedFolders[archivePath] = destFolder; | ||
285 | return destFolder; | ||
286 | } | ||
287 | } | ||
259 | 288 | ||
260 | if (resolvedFolders.ContainsKey(archivePath)) | 289 | // Don't include the last slash so find the penultimate one |
290 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); | ||
291 | |||
292 | if (penultimateSlashIndex >= 0) | ||
261 | { | 293 | { |
262 | m_log.DebugFormat( | 294 | // Remove the last section of path so that we can see if we've already resolved the parent |
263 | "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); | 295 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); |
264 | destFolder = resolvedFolders[archivePath]; | ||
265 | } | 296 | } |
266 | else | 297 | else |
267 | { | 298 | { |
268 | // Don't include the last slash so find the penultimate one | 299 | m_log.DebugFormat( |
269 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); | 300 | "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}", |
270 | 301 | originalArchivePath); | |
271 | if (penultimateSlashIndex >= 0) | 302 | archivePath = string.Empty; |
272 | { | 303 | return rootDestFolder; |
273 | // Remove the last section of path so that we can see if we've already resolved the parent | ||
274 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | m_log.DebugFormat( | ||
279 | "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}", | ||
280 | originalArchivePath); | ||
281 | archivePath = string.Empty; | ||
282 | destFolder = rootDestFolder; | ||
283 | } | ||
284 | } | 304 | } |
285 | } | 305 | } |
286 | } | 306 | } |
287 | 307 | ||
288 | if (null == destFolder) | 308 | return rootDestFolder; |
289 | destFolder = rootDestFolder; | ||
290 | |||
291 | return destFolder; | ||
292 | } | 309 | } |
293 | 310 | ||
294 | /// <summary> | 311 | /// <summary> |
@@ -314,24 +331,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
314 | string iarPathExisting, | 331 | string iarPathExisting, |
315 | string iarPathToReplicate, | 332 | string iarPathToReplicate, |
316 | Dictionary <string, InventoryFolderBase> resolvedFolders, | 333 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
317 | List<InventoryNodeBase> loadedNodes) | 334 | HashSet<InventoryNodeBase> loadedNodes) |
318 | { | 335 | { |
319 | string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | 336 | string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); |
320 | int i = 0; | ||
321 | 337 | ||
322 | while (i < rawDirsToCreate.Length) | 338 | for (int i = 0; i < rawDirsToCreate.Length; i++) |
323 | { | 339 | { |
324 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]); | 340 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]); |
325 | 341 | ||
342 | if (!rawDirsToCreate[i].Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR)) | ||
343 | continue; | ||
344 | |||
326 | int identicalNameIdentifierIndex | 345 | int identicalNameIdentifierIndex |
327 | = rawDirsToCreate[i].LastIndexOf( | 346 | = rawDirsToCreate[i].LastIndexOf( |
328 | ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); | 347 | ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); |
329 | 348 | ||
330 | if (identicalNameIdentifierIndex < 0) | ||
331 | { | ||
332 | i++; | ||
333 | continue; | ||
334 | } | ||
335 | string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); | 349 | string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); |
336 | 350 | ||
337 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); | 351 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); |
@@ -354,8 +368,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
354 | 368 | ||
355 | if (0 == i) | 369 | if (0 == i) |
356 | loadedNodes.Add(destFolder); | 370 | loadedNodes.Add(destFolder); |
357 | |||
358 | i++; | ||
359 | } | 371 | } |
360 | } | 372 | } |
361 | 373 | ||