aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs')
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs1204
1 files changed, 602 insertions, 602 deletions
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs
index f8acdea..c140965 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs
@@ -1,602 +1,602 @@
1/* 1/*
2 * Copyright (c) 2008 Intel Corporation 2 * Copyright (c) 2008 Intel Corporation
3 * All rights reserved. 3 * All rights reserved.
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * -- Redistributions of source code must retain the above copyright 8 * -- Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * -- Redistributions in binary form must reproduce the above copyright 10 * -- Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * -- Neither the name of the Intel Corporation nor the names of its 13 * -- Neither the name of the Intel Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from 14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission. 15 * this software without specific prior written permission.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS 20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.IO; 33using System.IO;
34using System.Text; 34using System.Text;
35using ExtensionLoader; 35using ExtensionLoader;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
38 38
39namespace OpenSim.Grid.AssetInventoryServer.Extensions 39namespace OpenSim.Grid.AssetInventoryServer.Extensions
40{ 40{
41 public class SimpleInventory : IExtension<AssetInventoryServer>, IInventoryProvider 41 public class SimpleInventory : IExtension<AssetInventoryServer>, IInventoryProvider
42 { 42 {
43 const string EXTENSION_NAME = "SimpleInventory"; // Used for metrics reporting 43 const string EXTENSION_NAME = "SimpleInventory"; // Used for metrics reporting
44 const string DEFAULT_INVENTORY_DIR = "SimpleInventory"; 44 const string DEFAULT_INVENTORY_DIR = "SimpleInventory";
45 45
46 AssetInventoryServer server; 46 AssetInventoryServer server;
47 Dictionary<Uri, InventoryCollection> inventories = new Dictionary<Uri, InventoryCollection>(); 47 Dictionary<Uri, InventoryCollection> inventories = new Dictionary<Uri, InventoryCollection>();
48 Dictionary<Uri, List<InventoryItem>> activeGestures = new Dictionary<Uri, List<InventoryItem>>(); 48 Dictionary<Uri, List<InventoryItem>> activeGestures = new Dictionary<Uri, List<InventoryItem>>();
49 Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); 49 Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer();
50 Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); 50 Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer();
51 51
52 public SimpleInventory() 52 public SimpleInventory()
53 { 53 {
54 } 54 }
55 55
56 #region Required Interfaces 56 #region Required Interfaces
57 57
58 public void Start(AssetInventoryServer server) 58 public void Start(AssetInventoryServer server)
59 { 59 {
60 this.server = server; 60 this.server = server;
61 61
62 LoadFiles(DEFAULT_INVENTORY_DIR); 62 LoadFiles(DEFAULT_INVENTORY_DIR);
63 63
64 Logger.Log.InfoFormat("Initialized the inventory index with data for {0} avatars", 64 Logger.Log.InfoFormat("Initialized the inventory index with data for {0} avatars",
65 inventories.Count); 65 inventories.Count);
66 } 66 }
67 67
68 public void Stop() 68 public void Stop()
69 { 69 {
70 } 70 }
71 71
72 public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item) 72 public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item)
73 { 73 {
74 item = null; 74 item = null;
75 BackendResponse ret; 75 BackendResponse ret;
76 76
77 InventoryCollection collection; 77 InventoryCollection collection;
78 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) 78 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item))
79 ret = BackendResponse.Success; 79 ret = BackendResponse.Success;
80 else 80 else
81 ret = BackendResponse.NotFound; 81 ret = BackendResponse.NotFound;
82 82
83 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); 83 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
84 return ret; 84 return ret;
85 } 85 }
86 86
87 public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder) 87 public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder)
88 { 88 {
89 folder = null; 89 folder = null;
90 BackendResponse ret; 90 BackendResponse ret;
91 91
92 InventoryCollection collection; 92 InventoryCollection collection;
93 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 93 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
94 ret = BackendResponse.Success; 94 ret = BackendResponse.Success;
95 else 95 else
96 ret = BackendResponse.NotFound; 96 ret = BackendResponse.NotFound;
97 97
98 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); 98 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
99 return ret; 99 return ret;
100 } 100 }
101 101
102 public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents) 102 public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents)
103 { 103 {
104 contents = null; 104 contents = null;
105 BackendResponse ret; 105 BackendResponse ret;
106 106
107 InventoryCollection collection; 107 InventoryCollection collection;
108 InventoryFolder folder; 108 InventoryFolder folder;
109 109
110 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 110 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
111 { 111 {
112 contents = new InventoryCollection(); 112 contents = new InventoryCollection();
113 contents.UserID = collection.UserID; 113 contents.UserID = collection.UserID;
114 contents.Folders = new Dictionary<UUID, InventoryFolder>(); 114 contents.Folders = new Dictionary<UUID, InventoryFolder>();
115 contents.Items = new Dictionary<UUID, InventoryItem>(); 115 contents.Items = new Dictionary<UUID, InventoryItem>();
116 116
117 foreach (InventoryBase invBase in folder.Children.Values) 117 foreach (InventoryBase invBase in folder.Children.Values)
118 { 118 {
119 if (invBase is InventoryItem) 119 if (invBase is InventoryItem)
120 { 120 {
121 InventoryItem invItem = invBase as InventoryItem; 121 InventoryItem invItem = invBase as InventoryItem;
122 contents.Items.Add(invItem.ID, invItem); 122 contents.Items.Add(invItem.ID, invItem);
123 } 123 }
124 else 124 else
125 { 125 {
126 InventoryFolder invFolder = invBase as InventoryFolder; 126 InventoryFolder invFolder = invBase as InventoryFolder;
127 contents.Folders.Add(invFolder.ID, invFolder); 127 contents.Folders.Add(invFolder.ID, invFolder);
128 } 128 }
129 } 129 }
130 130
131 ret = BackendResponse.Success; 131 ret = BackendResponse.Success;
132 } 132 }
133 else 133 else
134 { 134 {
135 ret = BackendResponse.NotFound; 135 ret = BackendResponse.NotFound;
136 } 136 }
137 137
138 server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); 138 server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
139 return ret; 139 return ret;
140 } 140 }
141 141
142 public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders) 142 public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders)
143 { 143 {
144 folders = null; 144 folders = null;
145 BackendResponse ret; 145 BackendResponse ret;
146 146
147 InventoryCollection collection; 147 InventoryCollection collection;
148 if (inventories.TryGetValue(owner, out collection)) 148 if (inventories.TryGetValue(owner, out collection))
149 { 149 {
150 folders = new List<InventoryFolder>(collection.Folders.Values); 150 folders = new List<InventoryFolder>(collection.Folders.Values);
151 return BackendResponse.Success; 151 return BackendResponse.Success;
152 } 152 }
153 else 153 else
154 { 154 {
155 ret = BackendResponse.NotFound; 155 ret = BackendResponse.NotFound;
156 } 156 }
157 157
158 server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now); 158 server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now);
159 return ret; 159 return ret;
160 } 160 }
161 161
162 public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory) 162 public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory)
163 { 163 {
164 inventory = null; 164 inventory = null;
165 BackendResponse ret; 165 BackendResponse ret;
166 166
167 if (inventories.TryGetValue(owner, out inventory)) 167 if (inventories.TryGetValue(owner, out inventory))
168 ret = BackendResponse.Success; 168 ret = BackendResponse.Success;
169 else 169 else
170 ret = BackendResponse.NotFound; 170 ret = BackendResponse.NotFound;
171 171
172 server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now); 172 server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now);
173 return ret; 173 return ret;
174 } 174 }
175 175
176 public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures) 176 public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures)
177 { 177 {
178 gestures = null; 178 gestures = null;
179 BackendResponse ret; 179 BackendResponse ret;
180 180
181 if (activeGestures.TryGetValue(owner, out gestures)) 181 if (activeGestures.TryGetValue(owner, out gestures))
182 ret = BackendResponse.Success; 182 ret = BackendResponse.Success;
183 else 183 else
184 ret = BackendResponse.NotFound; 184 ret = BackendResponse.NotFound;
185 185
186 server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now); 186 server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now);
187 return ret; 187 return ret;
188 } 188 }
189 189
190 public BackendResponse TryCreateItem(Uri owner, InventoryItem item) 190 public BackendResponse TryCreateItem(Uri owner, InventoryItem item)
191 { 191 {
192 BackendResponse ret; 192 BackendResponse ret;
193 193
194 InventoryCollection collection; 194 InventoryCollection collection;
195 if (inventories.TryGetValue(owner, out collection)) 195 if (inventories.TryGetValue(owner, out collection))
196 { 196 {
197 // Delete this item first if it already exists 197 // Delete this item first if it already exists
198 InventoryItem oldItem; 198 InventoryItem oldItem;
199 if (collection.Items.TryGetValue(item.ID, out oldItem)) 199 if (collection.Items.TryGetValue(item.ID, out oldItem))
200 TryDeleteItem(owner, item.ID); 200 TryDeleteItem(owner, item.ID);
201 201
202 try 202 try
203 { 203 {
204 // Create the file 204 // Create the file
205 SaveItem(item); 205 SaveItem(item);
206 206
207 // Add the item to the collection 207 // Add the item to the collection
208 lock (collection) collection.Items[item.ID] = item; 208 lock (collection) collection.Items[item.ID] = item;
209 209
210 // Add the item to its parent folder 210 // Add the item to its parent folder
211 InventoryFolder parent; 211 InventoryFolder parent;
212 if (collection.Folders.TryGetValue(item.Folder, out parent)) 212 if (collection.Folders.TryGetValue(item.Folder, out parent))
213 lock (parent.Children) parent.Children.Add(item.ID, item); 213 lock (parent.Children) parent.Children.Add(item.ID, item);
214 214
215 // Add active gestures to our list 215 // Add active gestures to our list
216 if (item.InvType == (int)InventoryType.Gesture && item.Flags == 1) 216 if (item.InvType == (int)InventoryType.Gesture && item.Flags == 1)
217 { 217 {
218 lock (activeGestures) 218 lock (activeGestures)
219 activeGestures[owner].Add(item); 219 activeGestures[owner].Add(item);
220 } 220 }
221 221
222 ret = BackendResponse.Success; 222 ret = BackendResponse.Success;
223 } 223 }
224 catch (Exception ex) 224 catch (Exception ex)
225 { 225 {
226 Logger.Log.Error(ex.Message); 226 Logger.Log.Error(ex.Message);
227 ret = BackendResponse.Failure; 227 ret = BackendResponse.Failure;
228 } 228 }
229 } 229 }
230 else 230 else
231 { 231 {
232 return BackendResponse.NotFound; 232 return BackendResponse.NotFound;
233 } 233 }
234 234
235 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now); 235 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now);
236 return ret; 236 return ret;
237 } 237 }
238 238
239 public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder) 239 public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder)
240 { 240 {
241 BackendResponse ret; 241 BackendResponse ret;
242 242
243 InventoryCollection collection; 243 InventoryCollection collection;
244 if (inventories.TryGetValue(owner, out collection)) 244 if (inventories.TryGetValue(owner, out collection))
245 { 245 {
246 // Delete this folder first if it already exists 246 // Delete this folder first if it already exists
247 InventoryFolder oldFolder; 247 InventoryFolder oldFolder;
248 if (collection.Folders.TryGetValue(folder.ID, out oldFolder)) 248 if (collection.Folders.TryGetValue(folder.ID, out oldFolder))
249 TryDeleteFolder(owner, folder.ID); 249 TryDeleteFolder(owner, folder.ID);
250 250
251 try 251 try
252 { 252 {
253 // Create the file 253 // Create the file
254 SaveFolder(folder); 254 SaveFolder(folder);
255 255
256 // Add the folder to the collection 256 // Add the folder to the collection
257 lock (collection) collection.Folders[folder.ID] = folder; 257 lock (collection) collection.Folders[folder.ID] = folder;
258 258
259 // Add the folder to its parent folder 259 // Add the folder to its parent folder
260 InventoryFolder parent; 260 InventoryFolder parent;
261 if (collection.Folders.TryGetValue(folder.ParentID, out parent)) 261 if (collection.Folders.TryGetValue(folder.ParentID, out parent))
262 lock (parent.Children) parent.Children.Add(folder.ID, folder); 262 lock (parent.Children) parent.Children.Add(folder.ID, folder);
263 263
264 ret = BackendResponse.Success; 264 ret = BackendResponse.Success;
265 } 265 }
266 catch (Exception ex) 266 catch (Exception ex)
267 { 267 {
268 Logger.Log.Error(ex.Message); 268 Logger.Log.Error(ex.Message);
269 ret = BackendResponse.Failure; 269 ret = BackendResponse.Failure;
270 } 270 }
271 } 271 }
272 else 272 else
273 { 273 {
274 ret = BackendResponse.NotFound; 274 ret = BackendResponse.NotFound;
275 } 275 }
276 276
277 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now); 277 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now);
278 return ret; 278 return ret;
279 } 279 }
280 280
281 public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder) 281 public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder)
282 { 282 {
283 BackendResponse ret; 283 BackendResponse ret;
284 284
285 lock (inventories) 285 lock (inventories)
286 { 286 {
287 if (!inventories.ContainsKey(owner)) 287 if (!inventories.ContainsKey(owner))
288 { 288 {
289 InventoryCollection collection = new InventoryCollection(); 289 InventoryCollection collection = new InventoryCollection();
290 collection.UserID = rootFolder.Owner; 290 collection.UserID = rootFolder.Owner;
291 collection.Folders = new Dictionary<UUID, InventoryFolder>(); 291 collection.Folders = new Dictionary<UUID, InventoryFolder>();
292 collection.Folders.Add(rootFolder.ID, rootFolder); 292 collection.Folders.Add(rootFolder.ID, rootFolder);
293 collection.Items = new Dictionary<UUID, InventoryItem>(); 293 collection.Items = new Dictionary<UUID, InventoryItem>();
294 294
295 inventories.Add(owner, collection); 295 inventories.Add(owner, collection);
296 296
297 ret = BackendResponse.Success; 297 ret = BackendResponse.Success;
298 } 298 }
299 else 299 else
300 { 300 {
301 ret = BackendResponse.Failure; 301 ret = BackendResponse.Failure;
302 } 302 }
303 } 303 }
304 304
305 if (ret == BackendResponse.Success) 305 if (ret == BackendResponse.Success)
306 { 306 {
307 string path = Path.Combine(DEFAULT_INVENTORY_DIR, rootFolder.Owner.ToString()); 307 string path = Path.Combine(DEFAULT_INVENTORY_DIR, rootFolder.Owner.ToString());
308 try 308 try
309 { 309 {
310 // Create the directory for this agent 310 // Create the directory for this agent
311 Directory.CreateDirectory(path); 311 Directory.CreateDirectory(path);
312 312
313 // Create an index.txt containing the UUID and URI for this agent 313 // Create an index.txt containing the UUID and URI for this agent
314 string[] index = new string[] { rootFolder.Owner.ToString(), owner.ToString() }; 314 string[] index = new string[] { rootFolder.Owner.ToString(), owner.ToString() };
315 File.WriteAllLines(Path.Combine(path, "index.txt"), index); 315 File.WriteAllLines(Path.Combine(path, "index.txt"), index);
316 316
317 // Create the root folder file 317 // Create the root folder file
318 SaveFolder(rootFolder); 318 SaveFolder(rootFolder);
319 } 319 }
320 catch (Exception ex) 320 catch (Exception ex)
321 { 321 {
322 Logger.Log.Error(ex.Message); 322 Logger.Log.Error(ex.Message);
323 ret = BackendResponse.Failure; 323 ret = BackendResponse.Failure;
324 } 324 }
325 } 325 }
326 326
327 server.MetricsProvider.LogInventoryCreateInventory(EXTENSION_NAME, ret, DateTime.Now); 327 server.MetricsProvider.LogInventoryCreateInventory(EXTENSION_NAME, ret, DateTime.Now);
328 return ret; 328 return ret;
329 } 329 }
330 330
331 public BackendResponse TryDeleteItem(Uri owner, UUID itemID) 331 public BackendResponse TryDeleteItem(Uri owner, UUID itemID)
332 { 332 {
333 BackendResponse ret; 333 BackendResponse ret;
334 334
335 InventoryCollection collection; 335 InventoryCollection collection;
336 InventoryItem item; 336 InventoryItem item;
337 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) 337 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item))
338 { 338 {
339 // Remove the item from its parent folder 339 // Remove the item from its parent folder
340 InventoryFolder parent; 340 InventoryFolder parent;
341 if (collection.Folders.TryGetValue(item.Folder, out parent)) 341 if (collection.Folders.TryGetValue(item.Folder, out parent))
342 lock (parent.Children) parent.Children.Remove(itemID); 342 lock (parent.Children) parent.Children.Remove(itemID);
343 343
344 // Remove the item from the collection 344 // Remove the item from the collection
345 lock (collection) collection.Items.Remove(itemID); 345 lock (collection) collection.Items.Remove(itemID);
346 346
347 // Remove from the active gestures list if applicable 347 // Remove from the active gestures list if applicable
348 if (item.InvType == (int)InventoryType.Gesture) 348 if (item.InvType == (int)InventoryType.Gesture)
349 { 349 {
350 lock (activeGestures) 350 lock (activeGestures)
351 { 351 {
352 for (int i = 0; i < activeGestures[owner].Count; i++) 352 for (int i = 0; i < activeGestures[owner].Count; i++)
353 { 353 {
354 if (activeGestures[owner][i].ID == itemID) 354 if (activeGestures[owner][i].ID == itemID)
355 { 355 {
356 activeGestures[owner].RemoveAt(i); 356 activeGestures[owner].RemoveAt(i);
357 break; 357 break;
358 } 358 }
359 } 359 }
360 } 360 }
361 } 361 }
362 362
363 // Delete the file. We don't know exactly what the file name is, 363 // Delete the file. We don't know exactly what the file name is,
364 // so search for it 364 // so search for it
365 string path = PathFromURI(owner); 365 string path = PathFromURI(owner);
366 string[] matches = Directory.GetFiles(path, String.Format("*{0}.item", itemID), SearchOption.TopDirectoryOnly); 366 string[] matches = Directory.GetFiles(path, String.Format("*{0}.item", itemID), SearchOption.TopDirectoryOnly);
367 foreach (string match in matches) 367 foreach (string match in matches)
368 { 368 {
369 try { File.Delete(match); } 369 try { File.Delete(match); }
370 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete file {0}: {1}", match, ex.Message); } 370 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete file {0}: {1}", match, ex.Message); }
371 } 371 }
372 372
373 ret = BackendResponse.Success; 373 ret = BackendResponse.Success;
374 } 374 }
375 else 375 else
376 { 376 {
377 ret = BackendResponse.NotFound; 377 ret = BackendResponse.NotFound;
378 } 378 }
379 379
380 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); 380 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
381 return ret; 381 return ret;
382 } 382 }
383 383
384 public BackendResponse TryDeleteFolder(Uri owner, UUID folderID) 384 public BackendResponse TryDeleteFolder(Uri owner, UUID folderID)
385 { 385 {
386 BackendResponse ret; 386 BackendResponse ret;
387 387
388 InventoryCollection collection; 388 InventoryCollection collection;
389 InventoryFolder folder; 389 InventoryFolder folder;
390 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 390 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
391 { 391 {
392 // Remove the folder from its parent folder 392 // Remove the folder from its parent folder
393 InventoryFolder parent; 393 InventoryFolder parent;
394 if (collection.Folders.TryGetValue(folder.ParentID, out parent)) 394 if (collection.Folders.TryGetValue(folder.ParentID, out parent))
395 lock (parent.Children) parent.Children.Remove(folderID); 395 lock (parent.Children) parent.Children.Remove(folderID);
396 396
397 // Remove the folder from the collection 397 // Remove the folder from the collection
398 lock (collection) collection.Items.Remove(folderID); 398 lock (collection) collection.Items.Remove(folderID);
399 399
400 // Delete the folder file. We don't know exactly what the file name is, 400 // Delete the folder file. We don't know exactly what the file name is,
401 // so search for it 401 // so search for it
402 string path = PathFromURI(owner); 402 string path = PathFromURI(owner);
403 string[] matches = Directory.GetFiles(path, String.Format("*{0}.folder", folderID), SearchOption.TopDirectoryOnly); 403 string[] matches = Directory.GetFiles(path, String.Format("*{0}.folder", folderID), SearchOption.TopDirectoryOnly);
404 foreach (string match in matches) 404 foreach (string match in matches)
405 { 405 {
406 try { File.Delete(match); } 406 try { File.Delete(match); }
407 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete folder file {0}: {1}", match, ex.Message); } 407 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete folder file {0}: {1}", match, ex.Message); }
408 } 408 }
409 409
410 ret = BackendResponse.Success; 410 ret = BackendResponse.Success;
411 } 411 }
412 else 412 else
413 { 413 {
414 ret = BackendResponse.NotFound; 414 ret = BackendResponse.NotFound;
415 } 415 }
416 416
417 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); 417 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
418 return ret; 418 return ret;
419 } 419 }
420 420
421 public BackendResponse TryPurgeFolder(Uri owner, UUID folderID) 421 public BackendResponse TryPurgeFolder(Uri owner, UUID folderID)
422 { 422 {
423 BackendResponse ret; 423 BackendResponse ret;
424 424
425 InventoryCollection collection; 425 InventoryCollection collection;
426 InventoryFolder folder; 426 InventoryFolder folder;
427 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 427 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
428 { 428 {
429 // Delete all of the folder children 429 // Delete all of the folder children
430 foreach (InventoryBase obj in new List<InventoryBase>(folder.Children.Values)) 430 foreach (InventoryBase obj in new List<InventoryBase>(folder.Children.Values))
431 { 431 {
432 if (obj is InventoryItem) 432 if (obj is InventoryItem)
433 { 433 {
434 TryDeleteItem(owner, (obj as InventoryItem).ID); 434 TryDeleteItem(owner, (obj as InventoryItem).ID);
435 } 435 }
436 else 436 else
437 { 437 {
438 InventoryFolder childFolder = obj as InventoryFolder; 438 InventoryFolder childFolder = obj as InventoryFolder;
439 TryPurgeFolder(owner, childFolder.ID); 439 TryPurgeFolder(owner, childFolder.ID);
440 TryDeleteFolder(owner, childFolder.ID); 440 TryDeleteFolder(owner, childFolder.ID);
441 } 441 }
442 } 442 }
443 443
444 ret = BackendResponse.Success; 444 ret = BackendResponse.Success;
445 } 445 }
446 else 446 else
447 { 447 {
448 ret = BackendResponse.NotFound; 448 ret = BackendResponse.NotFound;
449 } 449 }
450 450
451 server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); 451 server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
452 return ret; 452 return ret;
453 } 453 }
454 454
455 #endregion Required Interfaces 455 #endregion Required Interfaces
456 456
457 void SaveItem(InventoryItem item) 457 void SaveItem(InventoryItem item)
458 { 458 {
459 string filename = String.Format("{0}-{1}.item", SanitizeFilename(item.Name), item.ID); 459 string filename = String.Format("{0}-{1}.item", SanitizeFilename(item.Name), item.ID);
460 460
461 string path = Path.Combine(DEFAULT_INVENTORY_DIR, item.Owner.ToString()); 461 string path = Path.Combine(DEFAULT_INVENTORY_DIR, item.Owner.ToString());
462 path = Path.Combine(path, filename); 462 path = Path.Combine(path, filename);
463 463
464 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write)) 464 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
465 { 465 {
466 itemSerializer.Serialize(stream, item); 466 itemSerializer.Serialize(stream, item);
467 stream.Flush(); 467 stream.Flush();
468 } 468 }
469 } 469 }
470 470
471 void SaveFolder(InventoryFolder folder) 471 void SaveFolder(InventoryFolder folder)
472 { 472 {
473 string filename = String.Format("{0}-{1}.folder", SanitizeFilename(folder.Name), folder.ID); 473 string filename = String.Format("{0}-{1}.folder", SanitizeFilename(folder.Name), folder.ID);
474 474
475 string path = Path.Combine(DEFAULT_INVENTORY_DIR, folder.Owner.ToString()); 475 string path = Path.Combine(DEFAULT_INVENTORY_DIR, folder.Owner.ToString());
476 path = Path.Combine(path, filename); 476 path = Path.Combine(path, filename);
477 477
478 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write)) 478 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
479 { 479 {
480 folderSerializer.Serialize(stream, folder); 480 folderSerializer.Serialize(stream, folder);
481 stream.Flush(); 481 stream.Flush();
482 } 482 }
483 } 483 }
484 484
485 string SanitizeFilename(string filename) 485 string SanitizeFilename(string filename)
486 { 486 {
487 string output = filename; 487 string output = filename;
488 488
489 if (output.Length > 64) 489 if (output.Length > 64)
490 output = output.Substring(0, 64); 490 output = output.Substring(0, 64);
491 491
492 foreach (char i in Path.GetInvalidFileNameChars()) 492 foreach (char i in Path.GetInvalidFileNameChars())
493 output = output.Replace(i, '_'); 493 output = output.Replace(i, '_');
494 494
495 return output; 495 return output;
496 } 496 }
497 497
498 static string PathFromURI(Uri uri) 498 static string PathFromURI(Uri uri)
499 { 499 {
500 byte[] hash = OpenMetaverse.Utils.SHA1(Encoding.UTF8.GetBytes(uri.ToString())); 500 byte[] hash = OpenMetaverse.Utils.SHA1(Encoding.UTF8.GetBytes(uri.ToString()));
501 StringBuilder digest = new StringBuilder(40); 501 StringBuilder digest = new StringBuilder(40);
502 502
503 // Convert the hash to a hex string 503 // Convert the hash to a hex string
504 foreach (byte b in hash) 504 foreach (byte b in hash)
505 digest.AppendFormat(OpenMetaverse.Utils.EnUsCulture, "{0:x2}", b); 505 digest.AppendFormat(OpenMetaverse.Utils.EnUsCulture, "{0:x2}", b);
506 506
507 return Path.Combine(DEFAULT_INVENTORY_DIR, digest.ToString()); 507 return Path.Combine(DEFAULT_INVENTORY_DIR, digest.ToString());
508 } 508 }
509 509
510 void LoadFiles(string folder) 510 void LoadFiles(string folder)
511 { 511 {
512 // Try to create the directory if it doesn't already exist 512 // Try to create the directory if it doesn't already exist
513 if (!Directory.Exists(folder)) 513 if (!Directory.Exists(folder))
514 { 514 {
515 try { Directory.CreateDirectory(folder); } 515 try { Directory.CreateDirectory(folder); }
516 catch (Exception ex) 516 catch (Exception ex)
517 { 517 {
518 Logger.Log.Warn(ex.Message); 518 Logger.Log.Warn(ex.Message);
519 return; 519 return;
520 } 520 }
521 } 521 }
522 522
523 try 523 try
524 { 524 {
525 string[] agentFolders = Directory.GetDirectories(DEFAULT_INVENTORY_DIR); 525 string[] agentFolders = Directory.GetDirectories(DEFAULT_INVENTORY_DIR);
526 526
527 for (int i = 0; i < agentFolders.Length; i++) 527 for (int i = 0; i < agentFolders.Length; i++)
528 { 528 {
529 string foldername = agentFolders[i]; 529 string foldername = agentFolders[i];
530 string indexPath = Path.Combine(foldername, "index.txt"); 530 string indexPath = Path.Combine(foldername, "index.txt");
531 UUID ownerID = UUID.Zero; 531 UUID ownerID = UUID.Zero;
532 Uri owner = null; 532 Uri owner = null;
533 533
534 try 534 try
535 { 535 {
536 string[] index = File.ReadAllLines(indexPath); 536 string[] index = File.ReadAllLines(indexPath);
537 ownerID = UUID.Parse(index[0]); 537 ownerID = UUID.Parse(index[0]);
538 owner = new Uri(index[1]); 538 owner = new Uri(index[1]);
539 } 539 }
540 catch (Exception ex) 540 catch (Exception ex)
541 { 541 {
542 Logger.Log.WarnFormat("Failed loading the index file {0}: {1}", indexPath, ex.Message); 542 Logger.Log.WarnFormat("Failed loading the index file {0}: {1}", indexPath, ex.Message);
543 } 543 }
544 544
545 if (ownerID != UUID.Zero && owner != null) 545 if (ownerID != UUID.Zero && owner != null)
546 { 546 {
547 // Initialize the active gestures list for this agent 547 // Initialize the active gestures list for this agent
548 activeGestures.Add(owner, new List<InventoryItem>()); 548 activeGestures.Add(owner, new List<InventoryItem>());
549 549
550 InventoryCollection collection = new InventoryCollection(); 550 InventoryCollection collection = new InventoryCollection();
551 collection.UserID = ownerID; 551 collection.UserID = ownerID;
552 552
553 // Load all of the folders for this agent 553 // Load all of the folders for this agent
554 string[] folders = Directory.GetFiles(foldername, "*.folder", SearchOption.TopDirectoryOnly); 554 string[] folders = Directory.GetFiles(foldername, "*.folder", SearchOption.TopDirectoryOnly);
555 collection.Folders = new Dictionary<UUID,InventoryFolder>(folders.Length); 555 collection.Folders = new Dictionary<UUID,InventoryFolder>(folders.Length);
556 556
557 for (int j = 0; j < folders.Length; j++) 557 for (int j = 0; j < folders.Length; j++)
558 { 558 {
559 InventoryFolder invFolder = (InventoryFolder)folderSerializer.Deserialize( 559 InventoryFolder invFolder = (InventoryFolder)folderSerializer.Deserialize(
560 new FileStream(folders[j], FileMode.Open, FileAccess.Read)); 560 new FileStream(folders[j], FileMode.Open, FileAccess.Read));
561 collection.Folders[invFolder.ID] = invFolder; 561 collection.Folders[invFolder.ID] = invFolder;
562 } 562 }
563 563
564 // Iterate over the folders collection, adding children to their parents 564 // Iterate over the folders collection, adding children to their parents
565 foreach (InventoryFolder invFolder in collection.Folders.Values) 565 foreach (InventoryFolder invFolder in collection.Folders.Values)
566 { 566 {
567 InventoryFolder parent; 567 InventoryFolder parent;
568 if (collection.Folders.TryGetValue(invFolder.ParentID, out parent)) 568 if (collection.Folders.TryGetValue(invFolder.ParentID, out parent))
569 parent.Children[invFolder.ID] = invFolder; 569 parent.Children[invFolder.ID] = invFolder;
570 } 570 }
571 571
572 // Load all of the items for this agent 572 // Load all of the items for this agent
573 string[] files = Directory.GetFiles(foldername, "*.item", SearchOption.TopDirectoryOnly); 573 string[] files = Directory.GetFiles(foldername, "*.item", SearchOption.TopDirectoryOnly);
574 collection.Items = new Dictionary<UUID, InventoryItem>(files.Length); 574 collection.Items = new Dictionary<UUID, InventoryItem>(files.Length);
575 575
576 for (int j = 0; j < files.Length; j++) 576 for (int j = 0; j < files.Length; j++)
577 { 577 {
578 InventoryItem invItem = (InventoryItem)itemSerializer.Deserialize( 578 InventoryItem invItem = (InventoryItem)itemSerializer.Deserialize(
579 new FileStream(files[j], FileMode.Open, FileAccess.Read)); 579 new FileStream(files[j], FileMode.Open, FileAccess.Read));
580 collection.Items[invItem.ID] = invItem; 580 collection.Items[invItem.ID] = invItem;
581 581
582 // Add items to their parent folders 582 // Add items to their parent folders
583 InventoryFolder parent; 583 InventoryFolder parent;
584 if (collection.Folders.TryGetValue(invItem.Folder, out parent)) 584 if (collection.Folders.TryGetValue(invItem.Folder, out parent))
585 parent.Children[invItem.ID] = invItem; 585 parent.Children[invItem.ID] = invItem;
586 586
587 // Add active gestures to our list 587 // Add active gestures to our list
588 if (invItem.InvType == (int)InventoryType.Gesture && invItem.Flags != 0) 588 if (invItem.InvType == (int)InventoryType.Gesture && invItem.Flags != 0)
589 activeGestures[owner].Add(invItem); 589 activeGestures[owner].Add(invItem);
590 } 590 }
591 591
592 inventories.Add(owner, collection); 592 inventories.Add(owner, collection);
593 } 593 }
594 } 594 }
595 } 595 }
596 catch (Exception ex) 596 catch (Exception ex)
597 { 597 {
598 Logger.Log.ErrorFormat("Failed loading inventory from {0}: {1}", folder, ex.Message); 598 Logger.Log.ErrorFormat("Failed loading inventory from {0}: {1}", folder, ex.Message);
599 } 599 }
600 } 600 }
601 } 601 }
602} 602}