aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs')
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs465
1 files changed, 0 insertions, 465 deletions
diff --git a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs
deleted file mode 100644
index 451575f..0000000
--- a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs
+++ /dev/null
@@ -1,465 +0,0 @@
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;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using OpenSim.Framework;
37using OpenSim.Framework.Capabilities;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Services.Interfaces;
41using Caps = OpenSim.Framework.Capabilities.Caps;
42
43namespace OpenSim.Capabilities.Handlers
44{
45 public class FetchInvDescHandler
46 {
47 private static readonly ILog m_log =
48 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 private IInventoryService m_InventoryService;
51 private ILibraryService m_LibraryService;
52// private object m_fetchLock = new Object();
53
54 public FetchInvDescHandler(IInventoryService invService, ILibraryService libService)
55 {
56 m_InventoryService = invService;
57 m_LibraryService = libService;
58 }
59
60 public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
61 {
62// lock (m_fetchLock)
63// {
64// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request);
65
66 // nasty temporary hack here, the linden client falsely
67 // identifies the uuid 00000000-0000-0000-0000-000000000000
68 // as a string which breaks us
69 //
70 // correctly mark it as a uuid
71 //
72 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
73
74 // another hack <integer>1</integer> results in a
75 // System.ArgumentException: Object type System.Int32 cannot
76 // be converted to target type: System.Boolean
77 //
78 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
79 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
80
81 Hashtable hash = new Hashtable();
82 try
83 {
84 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
85 }
86 catch (LLSD.LLSDParseException e)
87 {
88 m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
89 m_log.Error("Request: " + request);
90 }
91
92 ArrayList foldersrequested = (ArrayList)hash["folders"];
93
94 string response = "";
95 string bad_folders_response = "";
96
97 for (int i = 0; i < foldersrequested.Count; i++)
98 {
99 string inventoryitemstr = "";
100 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
101
102 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
103
104 try
105 {
106 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
107 }
108 catch (Exception e)
109 {
110 m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
111 }
112 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
113
114 if (null == reply)
115 {
116 bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>";
117 }
118 else
119 {
120 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
121 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
122 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
123 }
124
125 response += inventoryitemstr;
126 }
127
128 if (response.Length == 0)
129 {
130 /* Viewers expect a bad_folders array when not available */
131 if (bad_folders_response.Length != 0)
132 {
133 response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
134 }
135 else
136 {
137 response = "<llsd><map><key>folders</key><array /></map></llsd>";
138 }
139 }
140 else
141 {
142 if (bad_folders_response.Length != 0)
143 {
144 response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
145 }
146 else
147 {
148 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
149 }
150 }
151
152// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
153 //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
154
155 return response;
156
157// }
158 }
159
160 /// <summary>
161 /// Construct an LLSD reply packet to a CAPS inventory request
162 /// </summary>
163 /// <param name="invFetch"></param>
164 /// <returns></returns>
165 private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
166 {
167 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
168 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
169 contents.agent_id = invFetch.owner_id;
170 contents.owner_id = invFetch.owner_id;
171 contents.folder_id = invFetch.folder_id;
172
173 reply.folders.Array.Add(contents);
174 InventoryCollection inv = new InventoryCollection();
175 inv.Folders = new List<InventoryFolderBase>();
176 inv.Items = new List<InventoryItemBase>();
177 int version = 0;
178 int descendents = 0;
179
180 inv
181 = Fetch(
182 invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
183 invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
184
185 if (inv != null && inv.Folders != null)
186 {
187 foreach (InventoryFolderBase invFolder in inv.Folders)
188 {
189 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
190 }
191
192 descendents += inv.Folders.Count;
193 }
194
195 if (inv != null && inv.Items != null)
196 {
197 foreach (InventoryItemBase invItem in inv.Items)
198 {
199 contents.items.Array.Add(ConvertInventoryItem(invItem));
200 }
201 }
202
203 contents.descendents = descendents;
204 contents.version = version;
205
206// m_log.DebugFormat(
207// "[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}",
208// invFetch.folder_id,
209// invFetch.fetch_items,
210// invFetch.fetch_folders,
211// contents.items.Array.Count,
212// contents.categories.Array.Count,
213// invFetch.owner_id);
214
215 return reply;
216 }
217
218 /// <summary>
219 /// Handle the caps inventory descendents fetch.
220 /// </summary>
221 /// <param name="agentID"></param>
222 /// <param name="folderID"></param>
223 /// <param name="ownerID"></param>
224 /// <param name="fetchFolders"></param>
225 /// <param name="fetchItems"></param>
226 /// <param name="sortOrder"></param>
227 /// <param name="version"></param>
228 /// <returns>An empty InventoryCollection if the inventory look up failed</returns>
229 private InventoryCollection Fetch(
230 UUID agentID, UUID folderID, UUID ownerID,
231 bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
232 {
233 //m_log.DebugFormat(
234 // "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
235 // fetchFolders, fetchItems, folderID, agentID);
236
237 // FIXME MAYBE: We're not handling sortOrder!
238
239 version = 0;
240 descendents = 0;
241
242 InventoryFolderImpl fold;
243 if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
244 {
245 if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
246 {
247 InventoryCollection ret = new InventoryCollection();
248 ret.Folders = new List<InventoryFolderBase>();
249 ret.Items = fold.RequestListOfItems();
250 descendents = ret.Folders.Count + ret.Items.Count;
251
252 return ret;
253 }
254 }
255
256 InventoryCollection contents = new InventoryCollection();
257
258 if (folderID != UUID.Zero)
259 {
260 InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID);
261
262 if (fetchedContents == null)
263 {
264 m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
265 return contents;
266 }
267
268 contents = fetchedContents;
269 InventoryFolderBase containingFolder = new InventoryFolderBase();
270 containingFolder.ID = folderID;
271 containingFolder.Owner = agentID;
272 containingFolder = m_InventoryService.GetFolder(containingFolder);
273
274 if (containingFolder != null)
275 {
276// m_log.DebugFormat(
277// "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
278// containingFolder.Name, containingFolder.ID, agentID);
279
280 version = containingFolder.Version;
281
282 if (fetchItems)
283 {
284 List<InventoryItemBase> itemsToReturn = contents.Items;
285 List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
286
287 // descendents must only include the links, not the linked items we add
288 descendents = originalItems.Count;
289
290 // Add target items for links in this folder before the links themselves.
291 foreach (InventoryItemBase item in originalItems)
292 {
293 if (item.AssetType == (int)AssetType.Link)
294 {
295 InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
296
297 // Take care of genuinely broken links where the target doesn't exist
298 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
299 // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
300 // rather than having to keep track of every folder requested in the recursion.
301 if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
302 itemsToReturn.Insert(0, linkedItem);
303 }
304 }
305
306 // Now scan for folder links and insert the items they target and those links at the head of the return data
307 foreach (InventoryItemBase item in originalItems)
308 {
309 if (item.AssetType == (int)AssetType.LinkFolder)
310 {
311 InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
312 List<InventoryItemBase> links = linkedFolderContents.Items;
313
314 itemsToReturn.InsertRange(0, links);
315
316 foreach (InventoryItemBase link in linkedFolderContents.Items)
317 {
318 // Take care of genuinely broken links where the target doesn't exist
319 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
320 // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
321 // rather than having to keep track of every folder requested in the recursion.
322 if (link != null)
323 {
324// m_log.DebugFormat(
325// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
326// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
327
328 InventoryItemBase linkedItem
329 = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
330
331 if (linkedItem != null)
332 itemsToReturn.Insert(0, linkedItem);
333 }
334 }
335 }
336 }
337 }
338
339// foreach (InventoryItemBase item in contents.Items)
340// {
341// m_log.DebugFormat(
342// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
343// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
344// }
345
346 // =====
347
348//
349// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
350// {
351// m_log.DebugFormat(
352// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
353// linkedItem.Name, folderID, agentID);
354//
355// contents.Items.Add(linkedItem);
356// }
357//
358// // If the folder requested contains links, then we need to send those folders first, otherwise the links
359// // will be broken in the viewer.
360// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
361// foreach (InventoryItemBase item in contents.Items)
362// {
363// if (item.AssetType == (int)AssetType.Link)
364// {
365// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
366//
367// // Take care of genuinely broken links where the target doesn't exist
368// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
369// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
370// // rather than having to keep track of every folder requested in the recursion.
371// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
372// {
373// // We don't need to send the folder if source and destination of the link are in the same
374// // folder.
375// if (linkedItem.Folder != containingFolder.ID)
376// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
377// }
378// }
379// }
380//
381// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
382// {
383// m_log.DebugFormat(
384// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
385// linkedItemFolderId, folderID, agentID);
386//
387// int dummyVersion;
388// InventoryCollection linkedCollection
389// = Fetch(
390// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
391//
392// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
393// linkedFolder.Owner = agentID;
394// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
395//
396//// contents.Folders.AddRange(linkedCollection.Folders);
397//
398// contents.Folders.Add(linkedFolder);
399// contents.Items.AddRange(linkedCollection.Items);
400// }
401// }
402 }
403 }
404 else
405 {
406 // Lost items don't really need a version
407 version = 1;
408 }
409
410 return contents;
411
412 }
413 /// <summary>
414 /// Convert an internal inventory folder object into an LLSD object.
415 /// </summary>
416 /// <param name="invFolder"></param>
417 /// <returns></returns>
418 private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
419 {
420 LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
421 llsdFolder.folder_id = invFolder.ID;
422 llsdFolder.parent_id = invFolder.ParentID;
423 llsdFolder.name = invFolder.Name;
424 llsdFolder.type = invFolder.Type;
425 llsdFolder.preferred_type = -1;
426
427 return llsdFolder;
428 }
429
430 /// <summary>
431 /// Convert an internal inventory item object into an LLSD object.
432 /// </summary>
433 /// <param name="invItem"></param>
434 /// <returns></returns>
435 private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
436 {
437 LLSDInventoryItem llsdItem = new LLSDInventoryItem();
438 llsdItem.asset_id = invItem.AssetID;
439 llsdItem.created_at = invItem.CreationDate;
440 llsdItem.desc = invItem.Description;
441 llsdItem.flags = (int)invItem.Flags;
442 llsdItem.item_id = invItem.ID;
443 llsdItem.name = invItem.Name;
444 llsdItem.parent_id = invItem.Folder;
445 llsdItem.type = invItem.AssetType;
446 llsdItem.inv_type = invItem.InvType;
447
448 llsdItem.permissions = new LLSDPermissions();
449 llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
450 llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
451 llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
452 llsdItem.permissions.group_id = invItem.GroupID;
453 llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
454 llsdItem.permissions.is_owner_group = invItem.GroupOwned;
455 llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
456 llsdItem.permissions.owner_id = invItem.Owner;
457 llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
458 llsdItem.sale_info = new LLSDSaleInfo();
459 llsdItem.sale_info.sale_price = invItem.SalePrice;
460 llsdItem.sale_info.sale_type = invItem.SaleType;
461
462 return llsdItem;
463 }
464 }
465} \ No newline at end of file