diff --git a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs
index 451575f8ec..a2f6740da7 100644
--- a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs
+++ b/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs
@@ -57,104 +57,113 @@ namespace OpenSim.Capabilities.Handlers
m_LibraryService = libService;
}
+
public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
-// lock (m_fetchLock)
-// {
-// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request);
- // nasty temporary hack here, the linden client falsely
- // identifies the uuid 00000000-0000-0000-0000-000000000000
- // as a string which breaks us
- //
- // correctly mark it as a uuid
- //
- request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000");
+ // nasty temporary hack here, the linden client falsely
+ // identifies the uuid 00000000-0000-0000-0000-000000000000
+ // as a string which breaks us
+ //
+ // correctly mark it as a uuid
+ //
+ request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000");
- // another hack 1 results in a
- // System.ArgumentException: Object type System.Int32 cannot
- // be converted to target type: System.Boolean
- //
- request = request.Replace("fetch_folders0", "fetch_folders0");
- request = request.Replace("fetch_folders1", "fetch_folders1");
+ // another hack 1 results in a
+ // System.ArgumentException: Object type System.Int32 cannot
+ // be converted to target type: System.Boolean
+ //
+ request = request.Replace("fetch_folders0", "fetch_folders0");
+ request = request.Replace("fetch_folders1", "fetch_folders1");
- Hashtable hash = new Hashtable();
+ Hashtable hash = new Hashtable();
+ try
+ {
+ hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
+ }
+ catch (LLSD.LLSDParseException e)
+ {
+ m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
+ m_log.Error("Request: " + request);
+ }
+
+ ArrayList foldersrequested = (ArrayList)hash["folders"];
+
+ string response = "";
+ string bad_folders_response = "";
+
+ List folders = new List();
+ for (int i = 0; i < foldersrequested.Count; i++)
+ {
+ Hashtable inventoryhash = (Hashtable)foldersrequested[i];
+
+ LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
+
try
{
- hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
+ LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
}
- catch (LLSD.LLSDParseException e)
+ catch (Exception e)
{
- m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
- m_log.Error("Request: " + request);
+ m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
+ continue;
}
-
- ArrayList foldersrequested = (ArrayList)hash["folders"];
-
- string response = "";
- string bad_folders_response = "";
- for (int i = 0; i < foldersrequested.Count; i++)
+ folders.Add(llsdRequest);
+ }
+
+ if (folders.Count > 0)
+ {
+ List invcollSet = Fetch(folders);
+ //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
+ if (invcollSet == null)
{
- string inventoryitemstr = "";
- Hashtable inventoryhash = (Hashtable)foldersrequested[i];
+ m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol.");
+ return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse);
+ }
- LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
+ string inventoryitemstr = string.Empty;
+ foreach (InventoryCollectionWithDescendents icoll in invcollSet)
+ {
+ LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents);
- try
- {
- LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
- }
- catch (Exception e)
- {
- m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
- }
- LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
-
- if (null == reply)
- {
- bad_folders_response += "" + llsdRequest.folder_id.ToString() + "";
- }
- else
- {
- inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
- inventoryitemstr = inventoryitemstr.Replace("", "");
- }
+ inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
+ inventoryitemstr = inventoryitemstr.Replace("", "");
response += inventoryitemstr;
}
+ }
- if (response.Length == 0)
+ if (response.Length == 0)
+ {
+ /* Viewers expect a bad_folders array when not available */
+ if (bad_folders_response.Length != 0)
{
- /* Viewers expect a bad_folders array when not available */
- if (bad_folders_response.Length != 0)
- {
- response = "";
- }
- else
- {
- response = "";
- }
+ response = "";
}
else
{
- if (bad_folders_response.Length != 0)
- {
- response = "";
- }
- else
- {
- response = "";
- }
+ response = "";
}
+ }
+ else
+ {
+ if (bad_folders_response.Length != 0)
+ {
+ response = "";
+ }
+ else
+ {
+ response = "";
+ }
+ }
-// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
- //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
+// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
+// m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
- return response;
+ return response;
-// }
}
///
@@ -203,18 +212,130 @@ namespace OpenSim.Capabilities.Handlers
contents.descendents = descendents;
contents.version = version;
-// m_log.DebugFormat(
-// "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
-// invFetch.folder_id,
-// invFetch.fetch_items,
-// invFetch.fetch_folders,
-// contents.items.Array.Count,
-// contents.categories.Array.Count,
-// invFetch.owner_id);
+ //m_log.DebugFormat(
+ // "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
+ // invFetch.folder_id,
+ // invFetch.fetch_items,
+ // invFetch.fetch_folders,
+ // contents.items.Array.Count,
+ // contents.categories.Array.Count,
+ // invFetch.owner_id);
return reply;
}
+ private LLSDInventoryDescendents ToLLSD(InventoryCollection inv, int descendents)
+ {
+ LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
+ LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
+ contents.agent_id = inv.OwnerID;
+ contents.owner_id = inv.OwnerID;
+ contents.folder_id = inv.FolderID;
+
+ reply.folders.Array.Add(contents);
+
+ if (inv.Folders != null)
+ {
+ foreach (InventoryFolderBase invFolder in inv.Folders)
+ {
+ contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
+ }
+
+ descendents += inv.Folders.Count;
+ }
+
+ if (inv.Items != null)
+ {
+ foreach (InventoryItemBase invItem in inv.Items)
+ {
+ contents.items.Array.Add(ConvertInventoryItem(invItem));
+ }
+ }
+
+ contents.descendents = descendents;
+ contents.version = inv.Version;
+
+ return reply;
+ }
+ ///
+ /// Old style. Soon to be deprecated.
+ ///
+ ///
+ ///
+ ///
+ ///
+ [Obsolete]
+ private string FetchInventoryDescendentsRequest(ArrayList foldersrequested, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
+ {
+ //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count);
+
+ string response = "";
+ string bad_folders_response = "";
+
+ for (int i = 0; i < foldersrequested.Count; i++)
+ {
+ string inventoryitemstr = "";
+ Hashtable inventoryhash = (Hashtable)foldersrequested[i];
+
+ LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
+
+ try
+ {
+ LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
+ }
+ catch (Exception e)
+ {
+ m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
+ }
+
+ LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
+
+ if (null == reply)
+ {
+ bad_folders_response += "" + llsdRequest.folder_id.ToString() + "";
+ }
+ else
+ {
+ inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
+ inventoryitemstr = inventoryitemstr.Replace("", "");
+ }
+
+ response += inventoryitemstr;
+ }
+
+ if (response.Length == 0)
+ {
+ /* Viewers expect a bad_folders array when not available */
+ if (bad_folders_response.Length != 0)
+ {
+ response = "";
+ }
+ else
+ {
+ response = "";
+ }
+ }
+ else
+ {
+ if (bad_folders_response.Length != 0)
+ {
+ response = "";
+ }
+ else
+ {
+ response = "";
+ }
+ }
+
+ // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
+ //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
+
+ return response;
+
+ // }
+ }
+
///
/// Handle the caps inventory descendents fetch.
///
@@ -226,6 +347,7 @@ namespace OpenSim.Capabilities.Handlers
///
///
/// An empty InventoryCollection if the inventory look up failed
+ [Obsolete]
private InventoryCollection Fetch(
UUID agentID, UUID folderID, UUID ownerID,
bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
@@ -264,7 +386,6 @@ namespace OpenSim.Capabilities.Handlers
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
return contents;
}
-
contents = fetchedContents;
InventoryFolderBase containingFolder = new InventoryFolderBase();
containingFolder.ID = folderID;
@@ -273,9 +394,9 @@ namespace OpenSim.Capabilities.Handlers
if (containingFolder != null)
{
-// m_log.DebugFormat(
-// "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
-// containingFolder.Name, containingFolder.ID, agentID);
+ //m_log.DebugFormat(
+ // "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
+ // containingFolder.Name, containingFolder.ID, agentID);
version = containingFolder.Version;
@@ -410,6 +531,160 @@ namespace OpenSim.Capabilities.Handlers
return contents;
}
+
+ private void AddLibraryFolders(List fetchFolders, List result)
+ {
+ InventoryFolderImpl fold;
+ if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
+ {
+ List libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner);
+ fetchFolders.RemoveAll(f => libfolders.Contains(f));
+
+ foreach (LLSDFetchInventoryDescendents f in libfolders)
+ {
+ if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
+ {
+ InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents();
+ ret.Collection = new InventoryCollection();
+ ret.Collection.Folders = new List();
+ ret.Collection.Items = fold.RequestListOfItems();
+ ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
+ ret.Collection.FolderID = f.folder_id;
+ ret.Collection.Version = fold.Version;
+
+ ret.Descendents = ret.Collection.Items.Count;
+
+ result.Add(ret);
+ }
+ }
+ }
+ }
+
+ private List Fetch(List fetchFolders)
+ {
+ //m_log.DebugFormat(
+ // "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);
+
+ // FIXME MAYBE: We're not handling sortOrder!
+
+ List result = new List();
+
+ AddLibraryFolders(fetchFolders, result);
+
+ if (fetchFolders.Count > 0)
+ {
+ UUID[] fids = new UUID[fetchFolders.Count];
+ int i = 0;
+ foreach (LLSDFetchInventoryDescendents f in fetchFolders)
+ fids[i++] = f.folder_id;
+
+ InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids);
+
+ if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0))
+ {
+ //m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id);
+ return null;
+ }
+
+ i = 0;
+ // Do some post-processing. May need to fetch more from inv server for links
+ foreach (InventoryCollection contents in fetchedContents)
+ {
+ InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents();
+ coll.Collection = contents;
+
+ // Find the original request
+ LLSDFetchInventoryDescendents freq = fetchFolders[i++];
+
+ // The inventory server isn't sending FolderID in the collection...
+ // Must fetch it individually
+ if (contents.FolderID == UUID.Zero)
+ {
+ InventoryFolderBase containingFolder = new InventoryFolderBase();
+ containingFolder.ID = freq.folder_id;
+ containingFolder.Owner = freq.owner_id;
+ containingFolder = m_InventoryService.GetFolder(containingFolder);
+
+ if (containingFolder != null)
+ {
+ contents.FolderID = containingFolder.ID;
+ contents.OwnerID = containingFolder.Owner;
+ contents.Version = containingFolder.Version;
+ }
+ else
+ {
+ m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
+ continue;
+ }
+ }
+
+ if (freq.fetch_items && contents.Items != null)
+ {
+ List itemsToReturn = contents.Items;
+ List originalItems = new List(itemsToReturn);
+
+ // descendents must only include the links, not the linked items we add
+ coll.Descendents = originalItems.Count;
+
+ // Add target items for links in this folder before the links themselves.
+ foreach (InventoryItemBase item in originalItems)
+ {
+ if (item.AssetType == (int)AssetType.Link)
+ {
+ InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
+
+ // Take care of genuinely broken links where the target doesn't exist
+ // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
+ // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
+ // rather than having to keep track of every folder requested in the recursion.
+ if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
+ {
+ itemsToReturn.Insert(0, linkedItem);
+ }
+ }
+ }
+
+ // Now scan for folder links and insert the items they target and those links at the head of the return data
+ foreach (InventoryItemBase item in originalItems)
+ {
+ if (item.AssetType == (int)AssetType.LinkFolder)
+ {
+ InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(coll.Collection.OwnerID, item.AssetID);
+ List links = linkedFolderContents.Items;
+
+ itemsToReturn.InsertRange(0, links);
+
+ foreach (InventoryItemBase link in linkedFolderContents.Items)
+ {
+ // Take care of genuinely broken links where the target doesn't exist
+ // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
+ // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
+ // rather than having to keep track of every folder requested in the recursion.
+ if (link != null)
+ {
+ //m_log.DebugFormat(
+ // "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
+ // link.Name, (AssetType)link.AssetType, item.AssetID, contents.FolderID);
+
+ InventoryItemBase linkedItem
+ = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
+
+ if (linkedItem != null)
+ itemsToReturn.Insert(0, linkedItem);
+ }
+ }
+ }
+ }
+ }
+
+ result.Add(coll);
+ }
+ }
+
+ return result;
+ }
+
+
///
/// Convert an internal inventory folder object into an LLSD object.
///
@@ -462,4 +737,10 @@ namespace OpenSim.Capabilities.Handlers
return llsdItem;
}
}
+
+ struct InventoryCollectionWithDescendents
+ {
+ public InventoryCollection Collection;
+ public int Descendents;
+ }
}
\ No newline at end of file
diff --git a/OpenSim/Framework/InventoryCollection.cs b/OpenSim/Framework/InventoryCollection.cs
index 70499022f8..59655eb3a7 100644
--- a/OpenSim/Framework/InventoryCollection.cs
+++ b/OpenSim/Framework/InventoryCollection.cs
@@ -37,6 +37,8 @@ namespace OpenSim.Framework
{
public List Folders;
public List Items;
- public UUID UserID;
+ public UUID OwnerID;
+ public UUID FolderID;
+ public int Version;
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index e402b0b784..30d1921de7 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -201,7 +201,7 @@ namespace OpenSim.Region.ClientStack.Linden
Scene.EventManager.OnRegisterCaps += RegisterCaps;
- int nworkers = 1; // was 2
+ int nworkers = 2; // was 2
if (ProcessQueuedRequestsAsync && m_workerThreads == null)
{
m_workerThreads = new Thread[nworkers];
@@ -365,7 +365,11 @@ namespace OpenSim.Region.ClientStack.Linden
requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null);
lock (responses)
+ {
+ if (responses.ContainsKey(requestID))
+ m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054");
responses[requestID] = response;
+ }
WebFetchInvDescModule.ProcessedRequestsCount++;
}
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
index 01814a15c6..eb7d3a94b7 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
{
InventoryFolderImpl folder = null;
InventoryCollection inv = new InventoryCollection();
- inv.UserID = m_Library.Owner;
+ inv.OwnerID = m_Library.Owner;
if (folderID != m_Library.ID)
{
@@ -87,6 +87,18 @@ namespace OpenSim.Region.CoreModules.Framework.Library
return inv;
}
+ public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
+ {
+ InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length];
+ int i = 0;
+ foreach (UUID fid in folderIDs)
+ {
+ invColl[i++] = GetFolderContent(principalID, fid);
+ }
+
+ return invColl;
+ }
+
///
/// Add a new folder to the user's inventory
///
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index e13ee42976..232cfdf7a9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -389,6 +389,25 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.GetFolderContent(userID, folderID);
}
+ public InventoryCollection[] GetMultipleFoldersContent(UUID userID, UUID[] folderIDs)
+ {
+ string invURL = GetInventoryServiceURL(userID);
+
+ if (invURL == null) // not there, forward to local inventory connector to resolve
+ lock (m_Lock)
+ return m_LocalGridInventoryService.GetMultipleFoldersContent(userID, folderIDs);
+
+ else
+ {
+ InventoryCollection[] coll = new InventoryCollection[folderIDs.Length];
+ int i = 0;
+ foreach (UUID fid in folderIDs)
+ coll[i++] = GetFolderContent(userID, fid);
+
+ return coll;
+ }
+ }
+
public List GetFolderItems(UUID userID, UUID folderID)
{
//m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
index 499ca5e3c5..71dc337584 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
if (m_Inventories.TryGetValue(userID, out inv))
{
c = new InventoryCollection();
- c.UserID = userID;
+ c.OwnerID = userID;
c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f)
{
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index cbe0e37d87..75dd200a18 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -195,6 +195,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return invCol;
}
+ public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
+ {
+ InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length];
+ int i = 0;
+ foreach (UUID fid in folderIDs)
+ {
+ invColl[i++] = GetFolderContent(principalID, fid);
+ }
+
+ return invColl;
+
+ }
+
public List GetFolderItems(UUID userID, UUID folderID)
{
return m_InventoryService.GetFolderItems(userID, folderID);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index 166e4a15e8..9beb382b4c 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -204,6 +204,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return invCol;
}
+ public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
+ {
+ return m_RemoteConnector.GetMultipleFoldersContent(principalID, folderIDs);
+ }
+
public List GetFolderItems(UUID userID, UUID folderID)
{
return m_RemoteConnector.GetFolderItems(userID, folderID);
diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
index 0288fa6bf3..4f01e36903 100644
--- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
+++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
@@ -41,7 +41,9 @@ using OpenSim.Server.Handlers.Base;
using log4net;
using OpenMetaverse;
-namespace OpenSim.Server.Handlers.Asset
+using System.Threading;
+
+namespace OpenSim.Server.Handlers.Inventory
{
public class XInventoryInConnector : ServiceConnector
{
@@ -123,6 +125,8 @@ namespace OpenSim.Server.Handlers.Asset
return HandleGetFolderForType(request);
case "GETFOLDERCONTENT":
return HandleGetFolderContent(request);
+ case "GETMULTIPLEFOLDERSCONTENT":
+ return HandleGetMultipleFoldersContent(request);
case "GETFOLDERITEMS":
return HandleGetFolderItems(request);
case "ADDFOLDER":
@@ -284,6 +288,8 @@ namespace OpenSim.Server.Handlers.Asset
InventoryCollection icoll = m_InventoryService.GetFolderContent(principal, folderID);
if (icoll != null)
{
+ result["FID"] = icoll.FolderID.ToString();
+ result["VERSION"] = icoll.Version.ToString();
Dictionary folders = new Dictionary();
int i = 0;
if (icoll.Folders != null)
@@ -314,7 +320,71 @@ namespace OpenSim.Server.Handlers.Asset
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
}
- byte[] HandleGetFolderItems(Dictionary request)
+ byte[] HandleGetMultipleFoldersContent(Dictionary request)
+ {
+ Dictionary resultSet = new Dictionary();
+ UUID principal = UUID.Zero;
+ UUID.TryParse(request["PRINCIPAL"].ToString(), out principal);
+ string folderIDstr = request["FOLDERS"].ToString();
+ int count = 0;
+ Int32.TryParse(request["COUNT"].ToString(), out count);
+
+ UUID[] fids = new UUID[count];
+ string[] uuids = folderIDstr.Split(',');
+ int i = 0;
+ foreach (string id in uuids)
+ {
+ UUID fid = UUID.Zero;
+ if (UUID.TryParse(id, out fid))
+ fids[i] = fid;
+ i += 1;
+ }
+
+ count = 0;
+ InventoryCollection[] icollList = m_InventoryService.GetMultipleFoldersContent(principal, fids);
+ if (icollList != null && icollList.Length > 0)
+ {
+ foreach (InventoryCollection icoll in icollList)
+ {
+ Dictionary result = new Dictionary();
+ result["FID"] = icoll.FolderID.ToString();
+ result["VERSION"] = icoll.Version.ToString();
+ result["OWNER"] = icoll.OwnerID.ToString();
+ Dictionary folders = new Dictionary();
+ i = 0;
+ if (icoll.Folders != null)
+ {
+ foreach (InventoryFolderBase f in icoll.Folders)
+ {
+ folders["folder_" + i.ToString()] = EncodeFolder(f);
+ i++;
+ }
+ result["FOLDERS"] = folders;
+ }
+ i = 0;
+ if (icoll.Items != null)
+ {
+ Dictionary items = new Dictionary();
+ foreach (InventoryItemBase it in icoll.Items)
+ {
+ items["item_" + i.ToString()] = EncodeItem(it);
+ i++;
+ }
+ result["ITEMS"] = items;
+ }
+
+ resultSet["F_" + fids[count++]] = result;
+ //m_log.DebugFormat("[XXX]: Sending {0} {1}", fids[count-1], icoll.FolderID);
+ }
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(resultSet);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ byte[] HandleGetFolderItems(Dictionary request)
{
Dictionary result = new Dictionary();
UUID principal = UUID.Zero;
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
index 574de892ce..c694d276df 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Services.Connectors
InventoryCollection inventory = new InventoryCollection();
inventory.Folders = new List();
inventory.Items = new List();
- inventory.UserID = principalID;
+ inventory.OwnerID = principalID;
try
{
@@ -235,7 +235,86 @@ namespace OpenSim.Services.Connectors
return inventory;
}
+
+ public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
+ {
+ InventoryCollection[] inventoryArr = new InventoryCollection[folderIDs.Length];
+ //m_log.DebugFormat("[XXX]: In GetMultipleFoldersContent {0}", folderIDs.Length);
+ try
+ {
+ Dictionary resultSet = MakeRequest("GETMULTIPLEFOLDERSCONTENT",
+ new Dictionary {
+ { "PRINCIPAL", principalID.ToString() },
+ { "FOLDERS", String.Join(",", folderIDs) },
+ { "COUNT", folderIDs.Length.ToString() }
+ });
+ if (!CheckReturn(resultSet))
+ return null;
+
+ int i = 0;
+ foreach (KeyValuePair kvp in resultSet)
+ {
+ InventoryCollection inventory = new InventoryCollection();
+ if (kvp.Key.StartsWith("F_"))
+ {
+ UUID fid = UUID.Zero;
+ if (UUID.TryParse(kvp.Key.Substring(2), out fid) && fid == folderIDs[i])
+ {
+ inventory.Folders = new List();
+ inventory.Items = new List();
+
+ Dictionary ret = (Dictionary)kvp.Value;
+
+ if (ret.ContainsKey("FID"))
+ {
+ if (!UUID.TryParse(ret["FID"].ToString(), out inventory.FolderID))
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Could not parse folder id {0}", ret["FID"].ToString());
+ }
+ else
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: FID key not present in response");
+
+ inventory.Version = -1;
+ if (ret.ContainsKey("VERSION"))
+ Int32.TryParse(ret["VERSION"].ToString(), out inventory.Version);
+ if (ret.ContainsKey("OWNER"))
+ UUID.TryParse(ret["OWNER"].ToString(), out inventory.OwnerID);
+
+ //m_log.DebugFormat("[XXX]: Received {0} ({1}) {2} {3}", inventory.FolderID, fid, inventory.Version, inventory.OwnerID);
+
+ Dictionary folders =
+ (Dictionary)ret["FOLDERS"];
+ Dictionary items =
+ (Dictionary)ret["ITEMS"];
+
+ foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
+ {
+ inventory.Folders.Add(BuildFolder((Dictionary)o));
+ }
+ foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
+ {
+ inventory.Items.Add(BuildItem((Dictionary)o));
+ }
+
+ inventoryArr[i] = inventory;
+ }
+ else
+ {
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Folder id does not match. Expected {0} got {1}",
+ folderIDs[i], fid);
+ }
+
+ i += 1;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleFoldersContent: {0}", e.Message);
+ }
+
+ return inventoryArr;
+ }
public List GetFolderItems(UUID principalID, UUID folderID)
{
Dictionary ret = MakeRequest("GETFOLDERITEMS",
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
index 9ded1c4d28..0331c66d2e 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
@@ -340,7 +340,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
InventoryCollection inventory = new InventoryCollection();
- inventory.UserID = userID;
+ inventory.OwnerID = userID;
NameValueCollection requestArgs = new NameValueCollection
{
@@ -371,6 +371,18 @@ namespace OpenSim.Services.Connectors.SimianGrid
return inventory;
}
+ public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
+ {
+ InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length];
+ int i = 0;
+ foreach (UUID fid in folderIDs)
+ {
+ invColl[i++] = GetFolderContent(principalID, fid);
+ }
+
+ return invColl;
+ }
+
///
/// Gets the items inside a folder
///
@@ -380,7 +392,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
public List GetFolderItems(UUID userID, UUID folderID)
{
InventoryCollection inventory = new InventoryCollection();
- inventory.UserID = userID;
+ inventory.OwnerID = userID;
NameValueCollection requestArgs = new NameValueCollection
{
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs
index 2c63240476..5f245e4dea 100644
--- a/OpenSim/Services/HypergridService/HGInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGInventoryService.cs
@@ -153,7 +153,14 @@ namespace OpenSim.Services.HypergridService
//public InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
//{
//}
-
+
+ // NOGO
+ //
+ public override InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderID)
+ {
+ return new InventoryCollection[0];
+ }
+
//public List GetFolderItems(UUID principalID, UUID folderID)
//{
//}
diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs
index 2805356cde..829f1699bd 100644
--- a/OpenSim/Services/Interfaces/IInventoryService.cs
+++ b/OpenSim/Services/Interfaces/IInventoryService.cs
@@ -76,6 +76,14 @@ namespace OpenSim.Services.Interfaces
///
/// Inventory content. null if the request failed.
InventoryCollection GetFolderContent(UUID userID, UUID folderID);
+
+ ///
+ /// Gets everything (folders and items) inside a folder
+ ///
+ ///
+ ///
+ /// Inventory content. null if the request failed.
+ InventoryCollection[] GetMultipleFoldersContent(UUID userID, UUID[] folderIDs);
///
/// Gets the items inside a folder
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 362ff8f8c1..6582b75cf0 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -291,7 +291,7 @@ namespace OpenSim.Services.InventoryService
//
//m_log.DebugFormat("[XINVENTORY SERVICE]: Fetch contents for folder {0}", folderID.ToString());
InventoryCollection inventory = new InventoryCollection();
- inventory.UserID = principalID;
+ inventory.OwnerID = principalID;
inventory.Folders = new List();
inventory.Items = new List();
@@ -315,8 +315,27 @@ namespace OpenSim.Services.InventoryService
inventory.Items.Add(ConvertToOpenSim(i));
}
+ InventoryFolderBase f = new InventoryFolderBase(folderID, principalID);
+ f = GetFolder(f);
+ if (f != null)
+ {
+ inventory.Version = f.Version;
+ inventory.OwnerID = f.Owner;
+ }
+ inventory.FolderID = folderID;
+
return inventory;
}
+
+ public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
+ {
+ InventoryCollection[] multiple = new InventoryCollection[folderIDs.Length];
+ int i = 0;
+ foreach (UUID fid in folderIDs)
+ multiple[i++] = GetFolderContent(principalID, fid);
+
+ return multiple;
+ }
public virtual List GetFolderItems(UUID principalID, UUID folderID)
{