aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Serialization/ArchiveConstants.cs29
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs110
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs54
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs50
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs2
6 files changed, 166 insertions, 87 deletions
diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs
index 475a9de..3143e3b 100644
--- a/OpenSim/Framework/Serialization/ArchiveConstants.cs
+++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Text;
30using OpenMetaverse; 31using OpenMetaverse;
31 32
32namespace OpenSim.Framework.Serialization 33namespace OpenSim.Framework.Serialization
@@ -171,6 +172,30 @@ namespace OpenSim.Framework.Serialization
171 public static string CreateOarObjectPath(string objectName, UUID uuid, Vector3 pos) 172 public static string CreateOarObjectPath(string objectName, UUID uuid, Vector3 pos)
172 { 173 {
173 return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos); 174 return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos);
174 } 175 }
176
177 /// <summary>
178 /// Extract a plain path from an IAR path
179 /// </summary>
180 /// <param name="iarPath"></param>
181 /// <returns></returns>
182 public static string ExtractPlainPathFromIarPath(string iarPath)
183 {
184 List<string> plainDirs = new List<string>();
185
186 string[] iarDirs = iarPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
187
188 foreach (string iarDir in iarDirs)
189 {
190 if (!iarDir.Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR))
191 plainDirs.Add(iarDir);
192
193 int i = iarDir.LastIndexOf(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
194
195 plainDirs.Add(iarDir.Remove(i));
196 }
197
198 return string.Join("/", plainDirs.ToArray());
199 }
175 } 200 }
176} 201} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 31dfe14..7683288 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,7 +98,7 @@ 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 try 103 try
97 { 104 {
@@ -100,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
100 int failedAssetRestores = 0; 107 int failedAssetRestores = 0;
101 int successfulItemRestores = 0; 108 int successfulItemRestores = 0;
102 109
103 List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>(); 110 HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
104 111
105 List<InventoryFolderBase> folderCandidates 112 List<InventoryFolderBase> folderCandidates
106 = InventoryArchiveUtils.FindFolderByPath( 113 = 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 }
@@ -205,14 +212,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
205 string iarPath, 212 string iarPath,
206 InventoryFolderBase rootDestFolder, 213 InventoryFolderBase rootDestFolder,
207 Dictionary <string, InventoryFolderBase> resolvedFolders, 214 Dictionary <string, InventoryFolderBase> resolvedFolders,
208 List<InventoryNodeBase> loadedNodes) 215 HashSet<InventoryNodeBase> loadedNodes)
209 { 216 {
210 string iarPathExisting = iarPath; 217 string iarPathExisting = iarPath;
211 218
212// m_log.DebugFormat( 219// m_log.DebugFormat(
213// "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); 220// "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
214 221
215 InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); 222 InventoryFolderBase destFolder
223 = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders);
216 224
217// m_log.DebugFormat( 225// m_log.DebugFormat(
218// "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", 226// "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]",
@@ -251,46 +259,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
251 { 259 {
252// string originalArchivePath = archivePath; 260// string originalArchivePath = archivePath;
253 261
254 InventoryFolderBase destFolder = null; 262 while (archivePath.Length > 0)
255
256 if (archivePath.Length > 0)
257 { 263 {
258 while (null == destFolder && archivePath.Length > 0) 264 m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath);
265
266 if (resolvedFolders.ContainsKey(archivePath))
267 {
268// m_log.DebugFormat(
269// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
270 return resolvedFolders[archivePath];
271 }
272 else
259 { 273 {
260// m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); 274 if (m_merge)
275 {
276 // TODO: Using m_invPath is totally wrong - what we need to do is strip the uuid from the
277 // iar name and try to find that instead.
278 string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath);
279 List<InventoryFolderBase> folderCandidates
280 = InventoryArchiveUtils.FindFolderByPath(
281 m_scene.InventoryService, m_userInfo.PrincipalID, plainPath);
282
283 if (folderCandidates.Count != 0)
284 {
285 InventoryFolderBase destFolder = folderCandidates[0];
286 resolvedFolders[archivePath] = destFolder;
287 return destFolder;
288 }
289 }
261 290
262 if (resolvedFolders.ContainsKey(archivePath)) 291 // Don't include the last slash so find the penultimate one
292 int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
293
294 if (penultimateSlashIndex >= 0)
263 { 295 {
264// m_log.DebugFormat( 296 // Remove the last section of path so that we can see if we've already resolved the parent
265// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); 297 archivePath = archivePath.Remove(penultimateSlashIndex + 1);
266 destFolder = resolvedFolders[archivePath];
267 } 298 }
268 else 299 else
269 { 300 {
270 // Don't include the last slash so find the penultimate one 301// m_log.DebugFormat(
271 int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); 302// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
272 303// originalArchivePath);
273 if (penultimateSlashIndex >= 0) 304 archivePath = string.Empty;
274 { 305 return rootDestFolder;
275 // Remove the last section of path so that we can see if we've already resolved the parent
276 archivePath = archivePath.Remove(penultimateSlashIndex + 1);
277 }
278 else
279 {
280// m_log.DebugFormat(
281// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
282// originalArchivePath);
283 archivePath = string.Empty;
284 destFolder = rootDestFolder;
285 }
286 } 306 }
287 } 307 }
288 } 308 }
289 309
290 if (null == destFolder) 310 return rootDestFolder;
291 destFolder = rootDestFolder;
292
293 return destFolder;
294 } 311 }
295 312
296 /// <summary> 313 /// <summary>
@@ -316,24 +333,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
316 string iarPathExisting, 333 string iarPathExisting,
317 string iarPathToReplicate, 334 string iarPathToReplicate,
318 Dictionary <string, InventoryFolderBase> resolvedFolders, 335 Dictionary <string, InventoryFolderBase> resolvedFolders,
319 List<InventoryNodeBase> loadedNodes) 336 HashSet<InventoryNodeBase> loadedNodes)
320 { 337 {
321 string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); 338 string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
322 int i = 0;
323 339
324 while (i < rawDirsToCreate.Length) 340 for (int i = 0; i < rawDirsToCreate.Length; i++)
325 { 341 {
326// m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]); 342// m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]);
327 343
344 if (!rawDirsToCreate[i].Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR))
345 continue;
346
328 int identicalNameIdentifierIndex 347 int identicalNameIdentifierIndex
329 = rawDirsToCreate[i].LastIndexOf( 348 = rawDirsToCreate[i].LastIndexOf(
330 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); 349 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
331 350
332 if (identicalNameIdentifierIndex < 0)
333 {
334 i++;
335 continue;
336 }
337 string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); 351 string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
338 352
339 newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); 353 newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
@@ -356,8 +370,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
356 370
357 if (0 == i) 371 if (0 == i)
358 loadedNodes.Add(destFolder); 372 loadedNodes.Add(destFolder);
359
360 i++;
361 } 373 }
362 } 374 }
363 375
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index f7a2b09..f03f2a1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -91,12 +91,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
91 91
92 scene.AddCommand( 92 scene.AddCommand(
93 this, "load iar", 93 this, "load iar",
94 "load iar <first> <last> <inventory path> <password> [<IAR path>]", 94 "load iar <first> <last> <inventory path> <password> [<IAR path>]",
95 //"load iar [--merge] <first> <last> <inventory path> <password> [<IAR path>]", 95 //"load iar [--merge] <first> <last> <inventory path> <password> [<IAR path>]",
96 "Load user inventory archive (IAR).", 96 "Load user inventory archive (IAR).",
97 //"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" 97 //"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
98 //+ "<first> is user's first name." + Environment.NewLine 98 //+ "<first> is user's first name." + Environment.NewLine
99 "<first> is user's first name." + Environment.NewLine 99 "<first> is user's first name." + Environment.NewLine
100 + "<last> is user's last name." + Environment.NewLine 100 + "<last> is user's last name." + Environment.NewLine
101 + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine 101 + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine
102 + "<password> is the user's password." + Environment.NewLine 102 + "<password> is the user's password." + Environment.NewLine
@@ -136,16 +136,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
136 if (handlerInventoryArchiveSaved != null) 136 if (handlerInventoryArchiveSaved != null)
137 handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); 137 handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException);
138 } 138 }
139 139
140 public bool ArchiveInventory( 140 public bool ArchiveInventory(
141 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) 141 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
142 { 142 {
143 return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>()); 143 return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>());
144 } 144 }
145 145
146 public bool ArchiveInventory( 146 public bool ArchiveInventory(
147 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, 147 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
148 Dictionary<string, object> options) 148 Dictionary<string, object> options)
149 { 149 {
150 if (m_scenes.Count > 0) 150 if (m_scenes.Count > 0)
151 { 151 {
@@ -184,8 +184,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
184 } 184 }
185 185
186 public bool ArchiveInventory( 186 public bool ArchiveInventory(
187 Guid id, string firstName, string lastName, string invPath, string pass, string savePath, 187 Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
188 Dictionary<string, object> options) 188 Dictionary<string, object> options)
189 { 189 {
190 if (m_scenes.Count > 0) 190 if (m_scenes.Count > 0)
191 { 191 {
@@ -224,13 +224,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
224 } 224 }
225 225
226 public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream) 226 public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream)
227 { 227 {
228 return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); 228 return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
229 } 229 }
230 230
231 public bool DearchiveInventory( 231 public bool DearchiveInventory(
232 string firstName, string lastName, string invPath, string pass, Stream loadStream, 232 string firstName, string lastName, string invPath, string pass, Stream loadStream,
233 Dictionary<string, object> options) 233 Dictionary<string, object> options)
234 { 234 {
235 if (m_scenes.Count > 0) 235 if (m_scenes.Count > 0)
236 { 236 {
@@ -241,10 +241,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
241 if (CheckPresence(userInfo.PrincipalID)) 241 if (CheckPresence(userInfo.PrincipalID))
242 { 242 {
243 InventoryArchiveReadRequest request; 243 InventoryArchiveReadRequest request;
244 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
244 245
245 try 246 try
246 { 247 {
247 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream); 248 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
248 } 249 }
249 catch (EntryPointNotFoundException e) 250 catch (EntryPointNotFoundException e)
250 { 251 {
@@ -273,8 +274,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
273 } 274 }
274 275
275 public bool DearchiveInventory( 276 public bool DearchiveInventory(
276 string firstName, string lastName, string invPath, string pass, string loadPath, 277 string firstName, string lastName, string invPath, string pass, string loadPath,
277 Dictionary<string, object> options) 278 Dictionary<string, object> options)
278 { 279 {
279 if (m_scenes.Count > 0) 280 if (m_scenes.Count > 0)
280 { 281 {
@@ -285,10 +286,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
285 if (CheckPresence(userInfo.PrincipalID)) 286 if (CheckPresence(userInfo.PrincipalID))
286 { 287 {
287 InventoryArchiveReadRequest request; 288 InventoryArchiveReadRequest request;
289 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
288 290
289 try 291 try
290 { 292 {
291 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath); 293 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge);
292 } 294 }
293 catch (EntryPointNotFoundException e) 295 catch (EntryPointNotFoundException e)
294 { 296 {
@@ -334,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
334 if (mainParams.Count < 6) 336 if (mainParams.Count < 6)
335 { 337 {
336 m_log.Error( 338 m_log.Error(
337 "[INVENTORY ARCHIVER]: usage is load iar <first name> <last name> <inventory path> <user password> [<load file path>]"); 339 "[INVENTORY ARCHIVER]: usage is load iar [--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
338 return; 340 return;
339 } 341 }
340 342
@@ -356,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
356 catch (InventoryArchiverException e) 358 catch (InventoryArchiverException e)
357 { 359 {
358 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); 360 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
359 } 361 }
360 } 362 }
361 363
362 /// <summary> 364 /// <summary>
@@ -469,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
469 /// Notify the client of loaded nodes if they are logged in 471 /// Notify the client of loaded nodes if they are logged in
470 /// </summary> 472 /// </summary>
471 /// <param name="loadedNodes">Can be empty. In which case, nothing happens</param> 473 /// <param name="loadedNodes">Can be empty. In which case, nothing happens</param>
472 private void UpdateClientWithLoadedNodes(UserAccount userInfo, List<InventoryNodeBase> loadedNodes) 474 private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet<InventoryNodeBase> loadedNodes)
473 { 475 {
474 if (loadedNodes.Count == 0) 476 if (loadedNodes.Count == 0)
475 return; 477 return;
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 4531bfd..2d80382 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -629,7 +629,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
629 UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); 629 UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
630 630
631 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); 631 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
632 List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>(); 632 HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>();
633 633
634 string folder1Name = "1"; 634 string folder1Name = "1";
635 string folder2aName = "2a"; 635 string folder2aName = "2a";
@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
644 644
645 { 645 {
646 // Test replication of path1 646 // Test replication of path1
647 new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) 647 new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
648 .ReplicateArchivePathToUserInventory( 648 .ReplicateArchivePathToUserInventory(
649 iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), 649 iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
650 foldersCreated, nodesLoaded); 650 foldersCreated, nodesLoaded);
@@ -661,7 +661,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
661 661
662 { 662 {
663 // Test replication of path2 663 // Test replication of path2
664 new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) 664 new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
665 .ReplicateArchivePathToUserInventory( 665 .ReplicateArchivePathToUserInventory(
666 iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), 666 iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
667 foldersCreated, nodesLoaded); 667 foldersCreated, nodesLoaded);
@@ -707,10 +707,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
707 707
708 string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); 708 string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
709 709
710 new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) 710 new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
711 .ReplicateArchivePathToUserInventory( 711 .ReplicateArchivePathToUserInventory(
712 itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), 712 itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
713 new Dictionary<string, InventoryFolderBase>(), new List<InventoryNodeBase>()); 713 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
714 714
715 List<InventoryFolderBase> folder1PostCandidates 715 List<InventoryFolderBase> folder1PostCandidates
716 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); 716 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
@@ -732,5 +732,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
732 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); 732 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b");
733 Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); 733 Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
734 } 734 }
735
736 /// <summary>
737 /// Test replication of a partly existing archive path to the user's inventory. This should create
738 /// a merged path.
739 /// </summary>
740 [Test]
741 public void TestMergeIarPath()
742 {
743 TestHelper.InMethod();
744 log4net.Config.XmlConfigurator.Configure();
745
746 Scene scene = SceneSetupHelpers.SetupScene("inventory");
747 UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
748
749 string folder1ExistingName = "a";
750 string folder2Name = "b";
751
752 InventoryFolderBase folder1
753 = UserInventoryTestUtils.CreateInventoryFolder(
754 scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
755
756 string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
757 string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
758
759 string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
760
761 new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true)
762 .ReplicateArchivePathToUserInventory(
763 itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
764 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
765
766 List<InventoryFolderBase> folder1PostCandidates
767 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
768 Assert.That(folder1PostCandidates.Count, Is.EqualTo(1));
769 Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID));
770
771 List<InventoryFolderBase> folder2PostCandidates
772 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b");
773 Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
774 }
735 } 775 }
736} \ No newline at end of file 776} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index 36dae6b..9c20d68 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -173,16 +173,16 @@ namespace OpenSim.Region.CoreModules.Framework.Library
173 m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); 173 m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
174 simpleName = GetInventoryPathFromName(simpleName); 174 simpleName = GetInventoryPathFromName(simpleName);
175 175
176 InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName); 176 InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false);
177 try 177 try
178 { 178 {
179 List<InventoryNodeBase> nodes = archread.Execute(); 179 HashSet<InventoryNodeBase> nodes = archread.Execute();
180 if (nodes != null && nodes.Count == 0) 180 if (nodes != null && nodes.Count == 0)
181 { 181 {
182 // didn't find the subfolder with the given name; place it on the top 182 // didn't find the subfolder with the given name; place it on the top
183 m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); 183 m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName);
184 archread.Close(); 184 archread.Close();
185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName); 185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
186 archread.Execute(); 186 archread.Execute();
187 } 187 }
188 foreach (InventoryNodeBase node in nodes) 188 foreach (InventoryNodeBase node in nodes)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index fe71ed5..5ae6439 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *