OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
InventoryArchiveUtils.cs
Go to the documentation of this file.
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 System.Reflection;
31 using System.Text;
32 using log4net;
33 using OpenMetaverse;
34 using OpenSim.Framework;
35 using OpenSim.Services.Interfaces;
36 
37 namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
38 {
42  public static class InventoryArchiveUtils
43  {
44 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 
46  // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings
47  public static readonly char ESCAPE_CHARACTER = '\\';
48 
49  // The character used to separate inventory path components (different folders and items)
50  public static readonly char PATH_DELIMITER = '/';
51 
74  public static InventoryFolderBase FindFolderByPath(
75  IInventoryService inventoryService, UUID userId, string path)
76  {
77  List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, userId, path);
78 
79  if (folders.Count == 0)
80  return null;
81  else
82  return folders[0];
83  }
84 
107  public static InventoryFolderBase FindFolderByPath(
108  IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
109  {
110  if (null == startFolder)
111  return null;
112 
113  List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, startFolder, path);
114 
115  if (folders.Count == 0)
116  return null;
117  else
118  return folders[0];
119  }
120 
142  public static List<InventoryFolderBase> FindFoldersByPath(
143  IInventoryService inventoryService, UUID userId, string path)
144  {
145  InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
146 
147  if (null == rootFolder)
148  return new List<InventoryFolderBase>();
149 
150  return FindFoldersByPath(inventoryService, rootFolder, path);
151  }
152 
174  public static List<InventoryFolderBase> FindFoldersByPath(
175  IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
176  {
177  List<InventoryFolderBase> foundFolders = new List<InventoryFolderBase>();
178 
179  if (path == string.Empty)
180  {
181  foundFolders.Add(startFolder);
182  return foundFolders;
183  }
184 
185  path = path.Trim();
186 
187  if (path == PATH_DELIMITER.ToString())
188  {
189  foundFolders.Add(startFolder);
190  return foundFolders;
191  }
192 
193  // If the path isn't just / then trim any starting extraneous slashes
194  path = path.TrimStart(new char[] { PATH_DELIMITER });
195 
196 // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Adjusted path in FindFolderByPath() is [{0}]", path);
197 
198  string[] components = SplitEscapedPath(path);
199  components[0] = UnescapePath(components[0]);
200 
201  //string[] components = path.Split(new string[] { PATH_DELIMITER.ToString() }, 2, StringSplitOptions.None);
202 
203  InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
204 
205 // m_log.DebugFormat(
206 // "Found {0} folders in {1} for {2}", contents.Folders.Count, startFolder.Name, startFolder.Owner);
207 
208  foreach (InventoryFolderBase folder in contents.Folders)
209  {
210  if (folder.Name == components[0])
211  {
212  if (components.Length > 1)
213  foundFolders.AddRange(FindFoldersByPath(inventoryService, folder, components[1]));
214  else
215  foundFolders.Add(folder);
216  }
217  }
218 
219  return foundFolders;
220  }
221 
244  public static InventoryItemBase FindItemByPath(
245  IInventoryService inventoryService, UUID userId, string path)
246  {
247  InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
248 
249  if (null == rootFolder)
250  return null;
251 
252  return FindItemByPath(inventoryService, rootFolder, path);
253  }
254 
271  public static InventoryItemBase FindItemByPath(
272  IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
273  {
274  List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
275 
276  if (foundItems.Count != 0)
277  return foundItems[0];
278  else
279  return null;
280  }
281 
282  public static List<InventoryItemBase> FindItemsByPath(
283  IInventoryService inventoryService, UUID userId, string path)
284  {
285  InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
286 
287  if (null == rootFolder)
288  return new List<InventoryItemBase>();
289 
290  return FindItemsByPath(inventoryService, rootFolder, path);
291  }
292 
309  public static List<InventoryItemBase> FindItemsByPath(
310  IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
311  {
312  List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
313 
314  // If the path isn't just / then trim any starting extraneous slashes
315  path = path.TrimStart(new char[] { PATH_DELIMITER });
316 
317  string[] components = SplitEscapedPath(path);
318  components[0] = UnescapePath(components[0]);
319 
320  //string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
321 
322  if (components.Length == 1)
323  {
324 // m_log.DebugFormat(
325 // "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
326 // components[0], startFolder.Name, startFolder.ID);
327 
328  List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
329 
330 // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
331 
332  foreach (InventoryItemBase item in items)
333  {
334 // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
335 
336  if (item.Name == components[0])
337  foundItems.Add(item);
338  }
339  }
340  else
341  {
342 // m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
343 
344  InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
345 
346  foreach (InventoryFolderBase folder in contents.Folders)
347  {
348  if (folder.Name == components[0])
349  foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
350  }
351  }
352 
353  return foundItems;
354  }
355 
365  public static string[] SplitEscapedPath(string path)
366  {
367 // m_log.DebugFormat("SPLITTING PATH {0}", path);
368 
369  bool singleEscapeChar = false;
370 
371  for (int i = 0; i < path.Length; i++)
372  {
373  if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
374  {
375  singleEscapeChar = true;
376  }
377  else
378  {
379  if (PATH_DELIMITER == path[i] && !singleEscapeChar)
380  return new string[2] { path.Remove(i), path.Substring(i + 1) };
381  else
382  singleEscapeChar = false;
383  }
384  }
385 
386  // We didn't find a delimiter
387  return new string[1] { path };
388  }
389 
395  public static string UnescapePath(string path)
396  {
397 // m_log.DebugFormat("ESCAPING PATH {0}", path);
398 
399  StringBuilder sb = new StringBuilder();
400 
401  bool singleEscapeChar = false;
402  for (int i = 0; i < path.Length; i++)
403  {
404  if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
405  singleEscapeChar = true;
406  else
407  singleEscapeChar = false;
408 
409  if (singleEscapeChar)
410  {
411  if (PATH_DELIMITER == path[i])
412  sb.Append(PATH_DELIMITER);
413  }
414  else
415  {
416  sb.Append(path[i]);
417  }
418  }
419 
420 // m_log.DebugFormat("ESCAPED PATH TO {0}", sb);
421 
422  return sb.ToString();
423  }
424 
432  public static string EscapeArchivePath(string path)
433  {
434  // Only encode ampersands (for escaping anything) and / (since this is used as general dir separator).
435  return path.Replace("&", "&amp;").Replace("/", "&#47;");
436  }
437 
443  public static string UnescapeArchivePath(string path)
444  {
445  return path.Replace("&#47;", "/").Replace("&amp;", "&");
446  }
447  }
448 }
Inventory Item - contains all the properties associated with an individual inventory piece...
virtual string Name
The name of the node (64 characters or less)
List< InventoryFolderBase > Folders
Used to serialize a whole inventory for transfer over the network.