aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/InventoryFolderImpl.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/InventoryFolderImpl.cs')
-rw-r--r--OpenSim/Framework/InventoryFolderImpl.cs466
1 files changed, 466 insertions, 0 deletions
diff --git a/OpenSim/Framework/InventoryFolderImpl.cs b/OpenSim/Framework/InventoryFolderImpl.cs
new file mode 100644
index 0000000..248783f
--- /dev/null
+++ b/OpenSim/Framework/InventoryFolderImpl.cs
@@ -0,0 +1,466 @@
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
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31
32namespace OpenSim.Framework
33{
34 public class InventoryFolderImpl : InventoryFolderBase
35 {
36 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
37
38 public static readonly string PATH_DELIMITER = "/";
39
40 /// <summary>
41 /// Items that are contained in this folder
42 /// </summary>
43 public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>();
44
45 /// <summary>
46 /// Child folders that are contained in this folder
47 /// </summary>
48 protected Dictionary<UUID, InventoryFolderImpl> m_childFolders = new Dictionary<UUID, InventoryFolderImpl>();
49
50 // Constructors
51 public InventoryFolderImpl(InventoryFolderBase folderbase)
52 {
53 Owner = folderbase.Owner;
54 ID = folderbase.ID;
55 Name = folderbase.Name;
56 ParentID = folderbase.ParentID;
57 Type = folderbase.Type;
58 Version = folderbase.Version;
59 }
60
61 public InventoryFolderImpl()
62 {
63 }
64
65 /// <summary>
66 /// Create a new subfolder.
67 /// </summary>
68 /// <param name="folderID"></param>
69 /// <param name="folderName"></param>
70 /// <param name="type"></param>
71 /// <returns>The newly created subfolder. Returns null if the folder already exists</returns>
72 public InventoryFolderImpl CreateChildFolder(UUID folderID, string folderName, ushort type)
73 {
74 lock (m_childFolders)
75 {
76 if (!m_childFolders.ContainsKey(folderID))
77 {
78 InventoryFolderImpl subFold = new InventoryFolderImpl();
79 subFold.Name = folderName;
80 subFold.ID = folderID;
81 subFold.Type = (short)type;
82 subFold.ParentID = this.ID;
83 subFold.Owner = Owner;
84 m_childFolders.Add(subFold.ID, subFold);
85
86 return subFold;
87 }
88 }
89
90 return null;
91 }
92
93 /// <summary>
94 /// Add a folder that already exists.
95 /// </summary>
96 /// <param name="folder"></param>
97 public void AddChildFolder(InventoryFolderImpl folder)
98 {
99 lock (m_childFolders)
100 {
101 folder.ParentID = ID;
102 m_childFolders[folder.ID] = folder;
103 }
104 }
105
106 /// <summary>
107 /// Does this folder contain the given child folder?
108 /// </summary>
109 /// <param name="folderID"></param>
110 /// <returns></returns>
111 public bool ContainsChildFolder(UUID folderID)
112 {
113 return m_childFolders.ContainsKey(folderID);
114 }
115
116 /// <summary>
117 /// Get a child folder
118 /// </summary>
119 /// <param name="folderID"></param>
120 /// <returns>The folder if it exists, null if it doesn't</returns>
121 public InventoryFolderImpl GetChildFolder(UUID folderID)
122 {
123 InventoryFolderImpl folder = null;
124
125 lock (m_childFolders)
126 {
127 m_childFolders.TryGetValue(folderID, out folder);
128 }
129
130 return folder;
131 }
132
133 /// <summary>
134 /// Removes the given child subfolder.
135 /// </summary>
136 /// <param name="folderID"></param>
137 /// <returns>
138 /// The folder removed, or null if the folder was not present.
139 /// </returns>
140 public InventoryFolderImpl RemoveChildFolder(UUID folderID)
141 {
142 InventoryFolderImpl removedFolder = null;
143
144 lock (m_childFolders)
145 {
146 if (m_childFolders.ContainsKey(folderID))
147 {
148 removedFolder = m_childFolders[folderID];
149 m_childFolders.Remove(folderID);
150 }
151 }
152
153 return removedFolder;
154 }
155
156 /// <summary>
157 /// Delete all the folders and items in this folder.
158 /// </summary>
159 public void Purge()
160 {
161 foreach (InventoryFolderImpl folder in m_childFolders.Values)
162 {
163 folder.Purge();
164 }
165
166 m_childFolders.Clear();
167 Items.Clear();
168 }
169
170 /// <summary>
171 /// Returns the item if it exists in this folder or in any of this folder's descendant folders
172 /// </summary>
173 /// <param name="itemID"></param>
174 /// <returns>null if the item is not found</returns>
175 public InventoryItemBase FindItem(UUID itemID)
176 {
177 lock (Items)
178 {
179 if (Items.ContainsKey(itemID))
180 {
181 return Items[itemID];
182 }
183 }
184
185 lock (m_childFolders)
186 {
187 foreach (InventoryFolderImpl folder in m_childFolders.Values)
188 {
189 InventoryItemBase item = folder.FindItem(itemID);
190
191 if (item != null)
192 {
193 return item;
194 }
195 }
196 }
197
198 return null;
199 }
200
201 public InventoryItemBase FindAsset(UUID assetID)
202 {
203 lock (Items)
204 {
205 foreach (InventoryItemBase item in Items.Values)
206 {
207 if (item.AssetID == assetID)
208 return item;
209 }
210 }
211
212 lock (m_childFolders)
213 {
214 foreach (InventoryFolderImpl folder in m_childFolders.Values)
215 {
216 InventoryItemBase item = folder.FindAsset(assetID);
217
218 if (item != null)
219 {
220 return item;
221 }
222 }
223 }
224
225 return null;
226 }
227
228 /// <summary>
229 /// Deletes an item if it exists in this folder or any children
230 /// </summary>
231 /// <param name="folderID"></param>
232 /// <returns></returns>
233 public bool DeleteItem(UUID itemID)
234 {
235 bool found = false;
236
237 lock (Items)
238 {
239 if (Items.ContainsKey(itemID))
240 {
241 Items.Remove(itemID);
242 return true;
243 }
244 }
245
246 lock (m_childFolders)
247 {
248 foreach (InventoryFolderImpl folder in m_childFolders.Values)
249 {
250 found = folder.DeleteItem(itemID);
251
252 if (found == true)
253 {
254 break;
255 }
256 }
257 }
258
259 return found;
260 }
261
262 /// <summary>
263 /// Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth
264 /// first.
265 /// </summary>
266 /// <returns>The requested folder if it exists, null if it does not.</returns>
267 public InventoryFolderImpl FindFolder(UUID folderID)
268 {
269 if (folderID == ID)
270 return this;
271
272 lock (m_childFolders)
273 {
274 foreach (InventoryFolderImpl folder in m_childFolders.Values)
275 {
276 InventoryFolderImpl returnFolder = folder.FindFolder(folderID);
277
278 if (returnFolder != null)
279 return returnFolder;
280 }
281 }
282
283 return null;
284 }
285
286 /// <summary>
287 /// Look through all child subfolders for a folder marked as one for a particular asset type, and return it.
288 /// </summary>
289 /// <param name="type"></param>
290 /// <returns>Returns null if no such folder is found</returns>
291 public InventoryFolderImpl FindFolderForType(int type)
292 {
293 lock (m_childFolders)
294 {
295 foreach (InventoryFolderImpl f in m_childFolders.Values)
296 {
297 if (f.Type == type)
298 return f;
299 }
300 }
301
302 return null;
303 }
304
305 /// <summary>
306 /// Find a folder given a PATH_DELIMITER delimited path starting from this folder
307 /// </summary>
308 ///
309 /// This method does not handle paths that contain multiple delimitors
310 ///
311 /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some
312 /// XPath like expression
313 ///
314 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
315 ///
316 /// <param name="path">
317 /// The path to the required folder.
318 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
319 /// </param>
320 /// <returns>null if the folder is not found</returns>
321 public InventoryFolderImpl FindFolderByPath(string path)
322 {
323 if (path == string.Empty)
324 return this;
325
326 path = path.Trim();
327
328 if (path == PATH_DELIMITER)
329 return this;
330
331 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
332
333 lock (m_childFolders)
334 {
335 foreach (InventoryFolderImpl folder in m_childFolders.Values)
336 {
337 if (folder.Name == components[0])
338 if (components.Length > 1)
339 return folder.FindFolderByPath(components[1]);
340 else
341 return folder;
342 }
343 }
344
345 // We didn't find a folder with the given name
346 return null;
347 }
348
349 /// <summary>
350 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
351 ///
352 /// This method does not handle paths that contain multiple delimitors
353 ///
354 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
355 /// XPath like expression
356 ///
357 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
358 /// </summary>
359 /// <param name="path">
360 /// The path to the required item.
361 /// </param>
362 /// <returns>null if the item is not found</returns>
363 public InventoryItemBase FindItemByPath(string path)
364 {
365 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
366
367 if (components.Length == 1)
368 {
369 lock (Items)
370 {
371 foreach (InventoryItemBase item in Items.Values)
372 {
373 if (item.Name == components[0])
374 return item;
375 }
376 }
377 }
378 else
379 {
380 lock (m_childFolders)
381 {
382 foreach (InventoryFolderImpl folder in m_childFolders.Values)
383 {
384 if (folder.Name == components[0])
385 return folder.FindItemByPath(components[1]);
386 }
387 }
388 }
389
390 // We didn't find an item or intermediate folder with the given name
391 return null;
392 }
393
394 /// <summary>
395 /// Return a copy of the list of child items in this folder. The items themselves are the originals.
396 /// </summary>
397 public List<InventoryItemBase> RequestListOfItems()
398 {
399 List<InventoryItemBase> itemList = new List<InventoryItemBase>();
400
401 lock (Items)
402 {
403 foreach (InventoryItemBase item in Items.Values)
404 {
405 itemList.Add(item);
406 }
407 }
408
409 //m_log.DebugFormat("[INVENTORY FOLDER IMPL]: Found {0} items", itemList.Count);
410
411 return itemList;
412 }
413
414 /// <summary>
415 /// Return a copy of the list of child folders in this folder. The folders themselves are the originals.
416 /// </summary>
417 public List<InventoryFolderBase> RequestListOfFolders()
418 {
419 List<InventoryFolderBase> folderList = new List<InventoryFolderBase>();
420
421 lock (m_childFolders)
422 {
423 foreach (InventoryFolderBase folder in m_childFolders.Values)
424 {
425 folderList.Add(folder);
426 }
427 }
428
429 return folderList;
430 }
431
432 public List<InventoryFolderImpl> RequestListOfFolderImpls()
433 {
434 List<InventoryFolderImpl> folderList = new List<InventoryFolderImpl>();
435
436 lock (m_childFolders)
437 {
438 foreach (InventoryFolderImpl folder in m_childFolders.Values)
439 {
440 folderList.Add(folder);
441 }
442 }
443
444 return folderList;
445 }
446
447 /// <value>
448 /// The total number of items in this folder and in the immediate child folders (though not from other
449 /// descendants).
450 /// </value>
451 public int TotalCount
452 {
453 get
454 {
455 int total = Items.Count;
456
457 foreach (InventoryFolderImpl folder in m_childFolders.Values)
458 {
459 total = total + folder.TotalCount;
460 }
461
462 return total;
463 }
464 }
465 }
466}