diff options
Diffstat (limited to '')
3 files changed, 175 insertions, 13 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs new file mode 100644 index 0000000..6d598d1 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Services.Interfaces; | ||
32 | |||
33 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | ||
34 | { | ||
35 | /// <summary> | ||
36 | /// Utility methods for inventory archiving | ||
37 | /// </summary> | ||
38 | public static class InventoryArchiveUtils | ||
39 | { | ||
40 | public static readonly string PATH_DELIMITER = "/"; | ||
41 | |||
42 | /// <summary> | ||
43 | /// Find a folder given a PATH_DELIMITER delimited path starting from this folder | ||
44 | /// </summary> | ||
45 | /// | ||
46 | /// This method does not handle paths that contain multiple delimitors | ||
47 | /// | ||
48 | /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some | ||
49 | /// XPath like expression | ||
50 | /// | ||
51 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | ||
52 | /// | ||
53 | /// <param name="inventoryService"> | ||
54 | /// Inventory service to query | ||
55 | /// </param> | ||
56 | /// <param name="startFolder"> | ||
57 | /// The folder from which the path starts | ||
58 | /// </param> | ||
59 | /// <param name="path"> | ||
60 | /// The path to the required folder. | ||
61 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. | ||
62 | /// </param> | ||
63 | /// <returns>null if the folder is not found</returns> | ||
64 | public static InventoryFolderBase FindFolderByPath( | ||
65 | IInventoryService inventoryService, InventoryFolderBase startFolder, string path) | ||
66 | { | ||
67 | if (path == string.Empty) | ||
68 | return startFolder; | ||
69 | |||
70 | path = path.Trim(); | ||
71 | |||
72 | if (path == PATH_DELIMITER) | ||
73 | return startFolder; | ||
74 | |||
75 | InventoryFolderBase foundFolder = null; | ||
76 | |||
77 | string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); | ||
78 | InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); | ||
79 | |||
80 | foreach (InventoryFolderBase folder in contents.Folders) | ||
81 | { | ||
82 | if (folder.Name == components[0]) | ||
83 | { | ||
84 | if (components.Length > 1) | ||
85 | return FindFolderByPath(inventoryService, foundFolder, components[1]); | ||
86 | else | ||
87 | return folder; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | // We didn't find a folder with the right name | ||
92 | return null; | ||
93 | } | ||
94 | |||
95 | /// <summary> | ||
96 | /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. | ||
97 | /// | ||
98 | /// This method does not handle paths that contain multiple delimitors | ||
99 | /// | ||
100 | /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some | ||
101 | /// XPath like expression | ||
102 | /// | ||
103 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | ||
104 | /// </summary> | ||
105 | /// | ||
106 | /// <param name="inventoryService"> | ||
107 | /// Inventory service to query | ||
108 | /// </param> | ||
109 | /// <param name="startFolder"> | ||
110 | /// The folder from which the path starts | ||
111 | /// </param> | ||
112 | /// <param name="path"> | ||
113 | /// <param name="path"> | ||
114 | /// The path to the required item. | ||
115 | /// </param> | ||
116 | /// <returns>null if the item is not found</returns> | ||
117 | public static InventoryItemBase FindItemByPath( | ||
118 | IInventoryService inventoryService, InventoryFolderBase startFolder, string path) | ||
119 | { | ||
120 | string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); | ||
121 | |||
122 | if (components.Length == 1) | ||
123 | { | ||
124 | List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); | ||
125 | foreach (InventoryItemBase item in items) | ||
126 | { | ||
127 | if (item.Name == components[0]) | ||
128 | return item; | ||
129 | } | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); | ||
134 | |||
135 | foreach (InventoryFolderBase folder in contents.Folders) | ||
136 | { | ||
137 | if (folder.Name == components[0]) | ||
138 | return FindItemByPath(inventoryService, folder, components[1]); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | // We didn't find an item or intermediate folder with the given name | ||
143 | return null; | ||
144 | } | ||
145 | } | ||
146 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index badabe0..dee4a5d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -158,7 +158,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
158 | /// <param name="inventoryFolder">The inventory folder to save</param> | 158 | /// <param name="inventoryFolder">The inventory folder to save</param> |
159 | /// <param name="path">The path to which the folder should be saved</param> | 159 | /// <param name="path">The path to which the folder should be saved</param> |
160 | /// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param> | 160 | /// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param> |
161 | protected void SaveInvFolder(InventoryFolderImpl inventoryFolder, string path, bool saveThisFolderItself) | 161 | protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself) |
162 | { | 162 | { |
163 | if (saveThisFolderItself) | 163 | if (saveThisFolderItself) |
164 | { | 164 | { |
@@ -173,15 +173,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
173 | m_archiveWriter.WriteDir(path); | 173 | m_archiveWriter.WriteDir(path); |
174 | } | 174 | } |
175 | 175 | ||
176 | List<InventoryFolderImpl> childFolders = inventoryFolder.RequestListOfFolderImpls(); | 176 | InventoryCollection contents |
177 | List<InventoryItemBase> items = inventoryFolder.RequestListOfItems(); | 177 | = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); |
178 | //List<InventoryFolderImpl> childFolders = inventoryFolder.RequestListOfFolderImpls(); | ||
179 | //List<InventoryItemBase> items = inventoryFolder.RequestListOfItems(); | ||
178 | 180 | ||
179 | /* | 181 | /* |
180 | Dictionary identicalFolderNames = new Dictionary<string, int>(); | 182 | Dictionary identicalFolderNames = new Dictionary<string, int>(); |
181 | 183 | ||
182 | foreach (InventoryFolderImpl folder in inventories) | 184 | foreach (InventoryFolderImpl folder in inventories) |
183 | { | 185 | { |
184 | |||
185 | if (!identicalFolderNames.ContainsKey(folder.Name)) | 186 | if (!identicalFolderNames.ContainsKey(folder.Name)) |
186 | identicalFolderNames[folder.Name] = 0; | 187 | identicalFolderNames[folder.Name] = 0; |
187 | else | 188 | else |
@@ -197,12 +198,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
197 | } | 198 | } |
198 | */ | 199 | */ |
199 | 200 | ||
200 | foreach (InventoryFolderImpl childFolder in childFolders) | 201 | foreach (InventoryFolderBase childFolder in contents.Folders) |
201 | { | 202 | { |
202 | SaveInvFolder(childFolder, path, true); | 203 | SaveInvFolder(childFolder, path, true); |
203 | } | 204 | } |
204 | 205 | ||
205 | foreach (InventoryItemBase item in items) | 206 | foreach (InventoryItemBase item in contents.Items) |
206 | { | 207 | { |
207 | SaveInvItem(item, path); | 208 | SaveInvItem(item, path); |
208 | } | 209 | } |
@@ -213,8 +214,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
213 | /// </summary> | 214 | /// </summary> |
214 | public void Execute() | 215 | public void Execute() |
215 | { | 216 | { |
216 | InventoryFolderImpl inventoryFolder = null; | 217 | InventoryFolderBase inventoryFolder = null; |
217 | InventoryItemBase inventoryItem = null; | 218 | InventoryItemBase inventoryItem = null; |
219 | InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.UserProfile.ID); | ||
218 | 220 | ||
219 | // XXX: Very temporarily, drop and refetch inventory to make sure we have any newly created items in cache | 221 | // XXX: Very temporarily, drop and refetch inventory to make sure we have any newly created items in cache |
220 | // This will disappear very soon once we stop using the old cached inventory. | 222 | // This will disappear very soon once we stop using the old cached inventory. |
@@ -223,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
223 | m_userInfo.FetchInventory(); | 225 | m_userInfo.FetchInventory(); |
224 | */ | 226 | */ |
225 | 227 | ||
228 | /* | ||
226 | if (!m_userInfo.HasReceivedInventory) | 229 | if (!m_userInfo.HasReceivedInventory) |
227 | { | 230 | { |
228 | // If the region server has access to the user admin service (by which users are created), | 231 | // If the region server has access to the user admin service (by which users are created), |
@@ -244,11 +247,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
244 | m_userInfo.FetchInventory(); | 247 | m_userInfo.FetchInventory(); |
245 | } | 248 | } |
246 | } | 249 | } |
250 | */ | ||
247 | 251 | ||
248 | bool foundStar = false; | 252 | bool foundStar = false; |
249 | 253 | ||
250 | // Eliminate double slashes and any leading / on the path. This might be better done within InventoryFolderImpl | 254 | // Eliminate double slashes and any leading / on the path. |
251 | // itself (possibly at a small loss in efficiency). | ||
252 | string[] components | 255 | string[] components |
253 | = m_invPath.Split( | 256 | = m_invPath.Split( |
254 | new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); | 257 | new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); |
@@ -273,18 +276,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
273 | // Therefore if we still start with a / after the split, then we need the root folder | 276 | // Therefore if we still start with a / after the split, then we need the root folder |
274 | if (m_invPath.Length == 0) | 277 | if (m_invPath.Length == 0) |
275 | { | 278 | { |
276 | inventoryFolder = m_userInfo.RootFolder; | 279 | inventoryFolder = rootFolder; |
277 | } | 280 | } |
278 | else | 281 | else |
279 | { | 282 | { |
280 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); | 283 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); |
281 | inventoryFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); | 284 | inventoryFolder |
285 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); | ||
286 | //inventoryFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); | ||
282 | } | 287 | } |
283 | 288 | ||
284 | // The path may point to an item instead | 289 | // The path may point to an item instead |
285 | if (inventoryFolder == null) | 290 | if (inventoryFolder == null) |
286 | { | 291 | { |
287 | inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath); | 292 | inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); |
293 | //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath); | ||
288 | } | 294 | } |
289 | 295 | ||
290 | m_archiveWriter = new TarArchiveWriter(m_saveStream); | 296 | m_archiveWriter = new TarArchiveWriter(m_saveStream); |
diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs index a444d91..daef38b 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs | |||
@@ -84,7 +84,17 @@ namespace OpenSim.Tests.Common.Mock | |||
84 | 84 | ||
85 | public List<InventoryItemBase> getInventoryInFolder(UUID folderID) | 85 | public List<InventoryItemBase> getInventoryInFolder(UUID folderID) |
86 | { | 86 | { |
87 | return new List<InventoryItemBase>(); | 87 | m_log.DebugFormat("[MOCK INV DB]: Getting items in folder {0}", folderID); |
88 | |||
89 | List<InventoryItemBase> items = new List<InventoryItemBase>(); | ||
90 | |||
91 | foreach (InventoryItemBase item in m_items.Values) | ||
92 | { | ||
93 | if (item.Folder == folderID) | ||
94 | items.Add(item); | ||
95 | } | ||
96 | |||
97 | return items; | ||
88 | } | 98 | } |
89 | 99 | ||
90 | public List<InventoryFolderBase> getUserRootFolders(UUID user) { return null; } | 100 | public List<InventoryFolderBase> getUserRootFolders(UUID user) { return null; } |