29 using System.Collections;
30 using System.Collections.Generic;
32 using System.Reflection;
36 using OpenMetaverse.StructuredData;
37 using OpenSim.Framework;
38 using OpenSim.Framework.Capabilities;
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Framework.Servers.HttpServer;
41 using OpenSim.Services.Interfaces;
44 namespace OpenSim.Capabilities.Handlers
48 private static readonly ILog m_log =
49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 m_InventoryService = invService;
59 m_LibraryService = libService;
74 request = request.Replace(
"<string>00000000-0000-0000-0000-000000000000</string>",
"<uuid>00000000-0000-0000-0000-000000000000</uuid>");
80 request = request.Replace(
"<key>fetch_folders</key><integer>0</integer>",
"<key>fetch_folders</key><boolean>0</boolean>");
81 request = request.Replace(
"<key>fetch_folders</key><integer>1</integer>",
"<key>fetch_folders</key><boolean>1</boolean>");
83 Hashtable hash =
new Hashtable();
86 hash = (Hashtable)LLSD.LLSDDeserialize(
Utils.StringToBytes(request));
88 catch (LLSD.LLSDParseException e)
90 m_log.ErrorFormat(
"[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
91 m_log.Error(
"Request: " + request);
94 ArrayList foldersrequested = (ArrayList)hash[
"folders"];
97 string bad_folders_response =
"";
99 List<LLSDFetchInventoryDescendents> folders =
new List<LLSDFetchInventoryDescendents>();
100 for (
int i = 0; i < foldersrequested.Count; i++)
102 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
108 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
112 m_log.Debug(
"[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
117 if (folders.Find(f => f.folder_id == llsdRequest.
folder_id) == null)
118 folders.Add(llsdRequest);
122 if (folders.Count > 0)
124 List<UUID> bad_folders =
new List<UUID>();
125 List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders);
128 if (invcollSet == null)
130 m_log.DebugFormat(
"[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol.");
131 #pragma warning disable 0612
132 return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse);
133 #pragma warning restore 0612
136 string inventoryitemstr = string.Empty;
141 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
142 inventoryitemstr = inventoryitemstr.Replace(
"<llsd><map><key>folders</key><array>",
"");
143 inventoryitemstr = inventoryitemstr.Replace(
"</array></map></llsd>",
"");
145 response += inventoryitemstr;
149 foreach (
UUID bad
in bad_folders)
150 bad_folders_response +=
"<uuid>" + bad +
"</uuid>";
153 if (response.Length == 0)
156 if (bad_folders_response.Length != 0)
158 response =
"<llsd><map><key>bad_folders</key><array>" + bad_folders_response +
"</array></map></llsd>";
162 response =
"<llsd><map><key>folders</key><array /></map></llsd>";
167 if (bad_folders_response.Length != 0)
169 response =
"<llsd><map><key>folders</key><array>" + response +
"</array><key>bad_folders</key><array>" + bad_folders_response +
"</array></map></llsd>";
173 response =
"<llsd><map><key>folders</key><array>" + response +
"</array></map></llsd>";
193 contents.agent_id = invFetch.owner_id;
194 contents.owner_id = invFetch.owner_id;
195 contents.folder_id = invFetch.folder_id;
197 reply.folders.Array.Add(contents);
199 inv.Folders =
new List<InventoryFolderBase>();
200 inv.Items =
new List<InventoryItemBase>();
204 #pragma warning disable 0612
208 #pragma warning restore 0612
210 if (inv != null && inv.Folders != null)
214 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
217 descendents += inv.Folders.Count;
220 if (inv != null && inv.Items != null)
224 contents.items.Array.Add(ConvertInventoryItem(invItem));
228 contents.descendents = descendents;
229 contents.version = version;
247 contents.agent_id = inv.OwnerID;
248 contents.owner_id = inv.OwnerID;
249 contents.folder_id = inv.FolderID;
251 reply.folders.Array.Add(contents);
257 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
260 descendents += inv.Folders.Count;
263 if (inv.
Items != null)
267 contents.items.Array.Add(ConvertInventoryItem(invItem));
271 contents.descendents = descendents;
272 contents.version = inv.Version;
288 string response =
"";
289 string bad_folders_response =
"";
291 for (
int i = 0; i < foldersrequested.Count; i++)
293 string inventoryitemstr =
"";
294 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
300 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
304 m_log.Debug(
"[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
311 bad_folders_response +=
"<uuid>" + llsdRequest.folder_id.ToString() +
"</uuid>";
315 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
316 inventoryitemstr = inventoryitemstr.Replace(
"<llsd><map><key>folders</key><array>",
"");
317 inventoryitemstr = inventoryitemstr.Replace(
"</array></map></llsd>",
"");
320 response += inventoryitemstr;
323 if (response.Length == 0)
326 if (bad_folders_response.Length != 0)
328 response =
"<llsd><map><key>bad_folders</key><array>" + bad_folders_response +
"</array></map></llsd>";
332 response =
"<llsd><map><key>folders</key><array /></map></llsd>";
337 if (bad_folders_response.Length != 0)
339 response =
"<llsd><map><key>folders</key><array>" + response +
"</array><key>bad_folders</key><array>" + bad_folders_response +
"</array></map></llsd>";
343 response =
"<llsd><map><key>folders</key><array>" + response +
"</array></map></llsd>";
368 UUID agentID, UUID folderID, UUID ownerID,
369 bool fetchFolders,
bool fetchItems,
int sortOrder, out
int version, out
int descendents)
381 if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
383 if ((fold = m_LibraryService.LibraryRootFolder.
FindFolder(folderID)) != null)
386 ret.Folders =
new List<InventoryFolderBase>();
387 ret.Items = fold.RequestListOfItems();
388 descendents = ret.Folders.Count + ret.Items.Count;
396 if (folderID !=
UUID.Zero)
398 InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID);
400 if (fetchedContents == null)
402 m_log.WarnFormat(
"[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
405 contents = fetchedContents;
407 containingFolder.ID = folderID;
408 containingFolder.Owner = agentID;
409 containingFolder = m_InventoryService.GetFolder(containingFolder);
411 if (containingFolder != null)
417 version = containingFolder.Version;
419 if (fetchItems && containingFolder.
Type != (
short)FolderType.Trash)
421 List<InventoryItemBase> itemsToReturn = contents.Items;
422 List<InventoryItemBase> originalItems =
new List<InventoryItemBase>(itemsToReturn);
425 descendents = originalItems.Count;
430 if (item.
AssetType == (
int)AssetType.Link)
438 if (linkedItem != null && linkedItem.
AssetType != (
int)AssetType.Link)
439 itemsToReturn.Insert(0, linkedItem);
556 private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> fetchFolders, List<InventoryCollectionWithDescendents> result)
559 if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
561 List<LLSDFetchInventoryDescendents> libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner);
562 fetchFolders.RemoveAll(f => libfolders.Contains(f));
570 InventoryCollectionWithDescendents ret =
new InventoryCollectionWithDescendents();
572 ret.Collection.Folders =
new List<InventoryFolderBase>();
573 ret.Collection.Items = fold.RequestListOfItems();
574 ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
575 ret.Collection.FolderID = f.folder_id;
576 ret.Collection.Version = fold.Version;
578 ret.Descendents = ret.Collection.Items.Count;
587 private List<InventoryCollectionWithDescendents> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders)
594 List<InventoryCollectionWithDescendents> result =
new List<InventoryCollectionWithDescendents>();
596 AddLibraryFolders(fetchFolders, result);
603 fetchFolders.Remove(zero);
604 BadFolder(zero, null, bad_folders);
607 if (fetchFolders.Count > 0)
609 UUID[] fids =
new UUID[fetchFolders.Count];
612 fids[i++] = f.folder_id;
616 InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids);
618 if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0))
620 m_log.WarnFormat(
"[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id);
622 BadFolder(freq, null, bad_folders);
633 InventoryCollectionWithDescendents coll =
new InventoryCollectionWithDescendents();
634 coll.Collection = contents;
636 if (BadFolder(freq, contents, bad_folders))
640 ProcessLinks(freq, coll);
652 if (contents == null)
654 bad_folders.Add(freq.folder_id);
663 containingFolder.ID = freq.folder_id;
664 containingFolder.Owner = freq.owner_id;
665 containingFolder = m_InventoryService.GetFolder(containingFolder);
667 if (containingFolder != null)
669 contents.FolderID = containingFolder.ID;
670 contents.OwnerID = containingFolder.Owner;
671 contents.Version = containingFolder.Version;
701 m_log.WarnFormat(
"[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
702 bad_folders.Add(freq.folder_id);
717 List<InventoryItemBase> itemsToReturn = contents.Items;
720 coll.Descendents = itemsToReturn.Count;
723 List<UUID> itemIDs =
new List<UUID>();
724 List<UUID> folderIDs =
new List<UUID>();
728 if (item.
AssetType == (
int)AssetType.Link)
738 if (folderIDs.Count > 0)
740 InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray());
743 if (linkedFolderContents == null)
746 List<InventoryItemBase> links = linkedFolderContents.Items;
748 itemsToReturn.InsertRange(0, links);
753 if (itemIDs.Count > 0)
755 InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
759 m_log.WarnFormat(
"[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
763 item.Owner = freq.owner_id;
764 foreach (UUID
id in itemIDs)
767 linked[i++] = m_InventoryService.GetItem(item);
783 if (linkedItem != null && linkedItem.
AssetType != (
int)AssetType.Link)
785 itemsToReturn.Insert(0, linkedItem);
803 llsdFolder.folder_id = invFolder.ID;
804 llsdFolder.parent_id = invFolder.ParentID;
805 llsdFolder.name = invFolder.Name;
806 llsdFolder.type = invFolder.Type;
807 llsdFolder.preferred_type = -1;
820 llsdItem.asset_id = invItem.AssetID;
821 llsdItem.created_at = invItem.CreationDate;
822 llsdItem.desc = invItem.Description;
823 llsdItem.flags = (int)invItem.
Flags;
831 llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
834 llsdItem.permissions.group_id = invItem.GroupID;
838 llsdItem.permissions.owner_id = invItem.Owner;
841 llsdItem.sale_info.sale_price = invItem.SalePrice;
842 llsdItem.sale_info.sale_type = invItem.SaleType;
OpenSim.Server.Handlers.Simulation.Utils Utils
InventoryFolderImpl FindFolder(UUID folderID)
Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth first.
FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s)
List< InventoryItemBase > Items
OpenSim.Framework.Capabilities.Caps Caps
LLSDPermissions permissions
Inventory Item - contains all the properties associated with an individual inventory piece...
InventoryCollection Collection
UUID ID
A UUID containing the ID for the inventory node itself
virtual string Name
The name of the node (64 characters or less)
List< InventoryFolderBase > Folders
string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
Used to serialize a whole inventory for transfer over the network.