InventoryServiceBase.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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 OpenSim 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. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using System.Threading;
  31. using OpenMetaverse;
  32. using log4net;
  33. namespace OpenSim.Framework.Communications
  34. {
  35. /// <summary>
  36. /// Abstract base class used by local and grid implementations of an inventory service.
  37. /// </summary>
  38. public abstract class InventoryServiceBase : IInventoryServices, IInterServiceInventoryServices
  39. {
  40. private static readonly ILog m_log
  41. = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  42. protected List<IInventoryDataPlugin> m_plugins = new List<IInventoryDataPlugin>();
  43. #region Plugin methods
  44. /// <summary>
  45. /// Add a new inventory data plugin - plugins will be requested in the order they were added.
  46. /// </summary>
  47. /// <param name="plugin">The plugin that will provide data</param>
  48. public void AddPlugin(IInventoryDataPlugin plugin)
  49. {
  50. m_plugins.Add(plugin);
  51. }
  52. /// <summary>
  53. /// Adds a new inventory data plugin - plugins will be requested in the order they were loaded.
  54. /// </summary>
  55. /// <param name="provider">The filename of the inventory server plugin DLL</param>
  56. public void AddPlugin(string provider, string connect)
  57. {
  58. PluginLoader<IInventoryDataPlugin> loader =
  59. new PluginLoader<IInventoryDataPlugin> (new InventoryDataInitialiser(connect));
  60. // loader will try to load all providers (MySQL, MSSQL, etc)
  61. // unless it is constrainted to the correct "Provider" entry in the addin.xml
  62. loader.Add ("/OpenSim/InventoryData", new PluginProviderFilter(provider));
  63. loader.Load();
  64. m_plugins.AddRange(loader.Plugins);
  65. }
  66. #endregion
  67. #region IInventoryServices methods
  68. public string Host
  69. {
  70. get { return "default"; }
  71. }
  72. public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
  73. {
  74. // m_log.DebugFormat("[AGENT INVENTORY]: Getting inventory skeleton for {0}", userId);
  75. InventoryFolderBase rootFolder = RequestRootFolder(userId);
  76. // Agent has no inventory structure yet.
  77. if (null == rootFolder)
  78. {
  79. return null;
  80. }
  81. List<InventoryFolderBase> userFolders = new List<InventoryFolderBase>();
  82. userFolders.Add(rootFolder);
  83. foreach (IInventoryDataPlugin plugin in m_plugins)
  84. {
  85. IList<InventoryFolderBase> folders = plugin.getFolderHierarchy(rootFolder.ID);
  86. userFolders.AddRange(folders);
  87. }
  88. // foreach (InventoryFolderBase folder in userFolders)
  89. // {
  90. // m_log.DebugFormat("[AGENT INVENTORY]: Got folder {0} {1}", folder.name, folder.folderID);
  91. // }
  92. return userFolders;
  93. }
  94. // See IInventoryServices
  95. public virtual bool HasInventoryForUser(UUID userID)
  96. {
  97. return false;
  98. }
  99. // See IInventoryServices
  100. public virtual InventoryFolderBase RequestRootFolder(UUID userID)
  101. {
  102. // FIXME: Probably doesn't do what was originally intended - only ever queries the first plugin
  103. foreach (IInventoryDataPlugin plugin in m_plugins)
  104. {
  105. return plugin.getUserRootFolder(userID);
  106. }
  107. return null;
  108. }
  109. // See IInventoryServices
  110. public bool CreateNewUserInventory(UUID user)
  111. {
  112. InventoryFolderBase existingRootFolder = RequestRootFolder(user);
  113. if (null != existingRootFolder)
  114. {
  115. m_log.WarnFormat(
  116. "[AGENT INVENTORY]: Did not create a new inventory for user {0} since they already have "
  117. + "a root inventory folder with id {1}",
  118. user, existingRootFolder.ID);
  119. }
  120. else
  121. {
  122. UsersInventory inven = new UsersInventory();
  123. inven.CreateNewInventorySet(user);
  124. AddNewInventorySet(inven);
  125. return true;
  126. }
  127. return false;
  128. }
  129. // See IInventoryServices
  130. public abstract void RequestInventoryForUser(UUID userID, InventoryReceiptCallback callback);
  131. public List<InventoryItemBase> GetActiveGestures(UUID userId)
  132. {
  133. foreach (IInventoryDataPlugin plugin in m_plugins)
  134. {
  135. return plugin.fetchActiveGestures(userId);
  136. }
  137. return new List<InventoryItemBase>();
  138. }
  139. #endregion
  140. #region Methods used by GridInventoryService
  141. public List<InventoryFolderBase> RequestSubFolders(UUID parentFolderID)
  142. {
  143. List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>();
  144. foreach (IInventoryDataPlugin plugin in m_plugins)
  145. {
  146. return plugin.getInventoryFolders(parentFolderID);
  147. }
  148. return inventoryList;
  149. }
  150. public List<InventoryItemBase> RequestFolderItems(UUID folderID)
  151. {
  152. List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
  153. foreach (IInventoryDataPlugin plugin in m_plugins)
  154. {
  155. itemsList = plugin.getInventoryInFolder(folderID);
  156. return itemsList;
  157. }
  158. return itemsList;
  159. }
  160. #endregion
  161. // See IInventoryServices
  162. public virtual bool AddFolder(InventoryFolderBase folder)
  163. {
  164. m_log.DebugFormat(
  165. "[AGENT INVENTORY]: Adding folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
  166. foreach (IInventoryDataPlugin plugin in m_plugins)
  167. {
  168. plugin.addInventoryFolder(folder);
  169. }
  170. // FIXME: Should return false on failure
  171. return true;
  172. }
  173. // See IInventoryServices
  174. public virtual bool UpdateFolder(InventoryFolderBase folder)
  175. {
  176. m_log.DebugFormat(
  177. "[AGENT INVENTORY]: Updating folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
  178. foreach (IInventoryDataPlugin plugin in m_plugins)
  179. {
  180. plugin.updateInventoryFolder(folder);
  181. }
  182. // FIXME: Should return false on failure
  183. return true;
  184. }
  185. // See IInventoryServices
  186. public virtual bool MoveFolder(InventoryFolderBase folder)
  187. {
  188. m_log.DebugFormat(
  189. "[AGENT INVENTORY]: Moving folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
  190. foreach (IInventoryDataPlugin plugin in m_plugins)
  191. {
  192. plugin.moveInventoryFolder(folder);
  193. }
  194. // FIXME: Should return false on failure
  195. return true;
  196. }
  197. // See IInventoryServices
  198. public virtual bool AddItem(InventoryItemBase item)
  199. {
  200. m_log.DebugFormat(
  201. "[AGENT INVENTORY]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder);
  202. foreach (IInventoryDataPlugin plugin in m_plugins)
  203. {
  204. plugin.addInventoryItem(item);
  205. }
  206. // FIXME: Should return false on failure
  207. return true;
  208. }
  209. // See IInventoryServices
  210. public virtual bool UpdateItem(InventoryItemBase item)
  211. {
  212. m_log.InfoFormat(
  213. "[AGENT INVENTORY]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder);
  214. foreach (IInventoryDataPlugin plugin in m_plugins)
  215. {
  216. plugin.updateInventoryItem(item);
  217. }
  218. // FIXME: Should return false on failure
  219. return true;
  220. }
  221. // See IInventoryServices
  222. public virtual bool DeleteItem(InventoryItemBase item)
  223. {
  224. m_log.InfoFormat(
  225. "[AGENT INVENTORY]: Deleting item {0} {1} from folder {2}", item.Name, item.ID, item.Folder);
  226. foreach (IInventoryDataPlugin plugin in m_plugins)
  227. {
  228. plugin.deleteInventoryItem(item.ID);
  229. }
  230. // FIXME: Should return false on failure
  231. return true;
  232. }
  233. /// <summary>
  234. /// Purge a folder of all items items and subfolders.
  235. ///
  236. /// FIXME: Really nasty in a sense, because we have to query the database to get information we may
  237. /// already know... Needs heavy refactoring.
  238. /// </summary>
  239. /// <param name="folder"></param>
  240. public virtual bool PurgeFolder(InventoryFolderBase folder)
  241. {
  242. m_log.DebugFormat(
  243. "[AGENT INVENTORY]: Purging folder {0} {1} of its contents", folder.Name, folder.ID);
  244. List<InventoryFolderBase> subFolders = RequestSubFolders(folder.ID);
  245. foreach (InventoryFolderBase subFolder in subFolders)
  246. {
  247. // m_log.DebugFormat("[AGENT INVENTORY]: Deleting folder {0} {1}", subFolder.Name, subFolder.ID);
  248. foreach (IInventoryDataPlugin plugin in m_plugins)
  249. {
  250. plugin.deleteInventoryFolder(subFolder.ID);
  251. }
  252. }
  253. List<InventoryItemBase> items = RequestFolderItems(folder.ID);
  254. foreach (InventoryItemBase item in items)
  255. {
  256. DeleteItem(item);
  257. }
  258. // FIXME: Should return false on failure
  259. return true;
  260. }
  261. private void AddNewInventorySet(UsersInventory inventory)
  262. {
  263. foreach (InventoryFolderBase folder in inventory.Folders.Values)
  264. {
  265. AddFolder(folder);
  266. }
  267. }
  268. /// <summary>
  269. /// Used to create a new user inventory.
  270. /// </summary>
  271. private class UsersInventory
  272. {
  273. public Dictionary<UUID, InventoryFolderBase> Folders = new Dictionary<UUID, InventoryFolderBase>();
  274. public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>();
  275. public virtual void CreateNewInventorySet(UUID user)
  276. {
  277. InventoryFolderBase folder = new InventoryFolderBase();
  278. folder.ParentID = UUID.Zero;
  279. folder.Owner = user;
  280. folder.ID = UUID.Random();
  281. folder.Name = "My Inventory";
  282. folder.Type = (short)AssetType.Folder;
  283. folder.Version = 1;
  284. Folders.Add(folder.ID, folder);
  285. UUID rootFolder = folder.ID;
  286. folder = new InventoryFolderBase();
  287. folder.ParentID = rootFolder;
  288. folder.Owner = user;
  289. folder.ID = UUID.Random();
  290. folder.Name = "Animations";
  291. folder.Type = (short)AssetType.Animation;
  292. folder.Version = 1;
  293. Folders.Add(folder.ID, folder);
  294. folder = new InventoryFolderBase();
  295. folder.ParentID = rootFolder;
  296. folder.Owner = user;
  297. folder.ID = UUID.Random();
  298. folder.Name = "Body Parts";
  299. folder.Type = (short)AssetType.Bodypart;
  300. folder.Version = 1;
  301. Folders.Add(folder.ID, folder);
  302. folder = new InventoryFolderBase();
  303. folder.ParentID = rootFolder;
  304. folder.Owner = user;
  305. folder.ID = UUID.Random();
  306. folder.Name = "Calling Cards";
  307. folder.Type = (short)AssetType.CallingCard;
  308. folder.Version = 1;
  309. Folders.Add(folder.ID, folder);
  310. folder = new InventoryFolderBase();
  311. folder.ParentID = rootFolder;
  312. folder.Owner = user;
  313. folder.ID = UUID.Random();
  314. folder.Name = "Clothing";
  315. folder.Type = (short)AssetType.Clothing;
  316. folder.Version = 1;
  317. Folders.Add(folder.ID, folder);
  318. folder = new InventoryFolderBase();
  319. folder.ParentID = rootFolder;
  320. folder.Owner = user;
  321. folder.ID = UUID.Random();
  322. folder.Name = "Gestures";
  323. folder.Type = (short)AssetType.Gesture;
  324. folder.Version = 1;
  325. Folders.Add(folder.ID, folder);
  326. folder = new InventoryFolderBase();
  327. folder.ParentID = rootFolder;
  328. folder.Owner = user;
  329. folder.ID = UUID.Random();
  330. folder.Name = "Landmarks";
  331. folder.Type = (short)AssetType.Landmark;
  332. folder.Version = 1;
  333. Folders.Add(folder.ID, folder);
  334. folder = new InventoryFolderBase();
  335. folder.ParentID = rootFolder;
  336. folder.Owner = user;
  337. folder.ID = UUID.Random();
  338. folder.Name = "Lost And Found";
  339. folder.Type = (short)AssetType.LostAndFoundFolder;
  340. folder.Version = 1;
  341. Folders.Add(folder.ID, folder);
  342. folder = new InventoryFolderBase();
  343. folder.ParentID = rootFolder;
  344. folder.Owner = user;
  345. folder.ID = UUID.Random();
  346. folder.Name = "Notecards";
  347. folder.Type = (short)AssetType.Notecard;
  348. folder.Version = 1;
  349. Folders.Add(folder.ID, folder);
  350. folder = new InventoryFolderBase();
  351. folder.ParentID = rootFolder;
  352. folder.Owner = user;
  353. folder.ID = UUID.Random();
  354. folder.Name = "Objects";
  355. folder.Type = (short)AssetType.Object;
  356. folder.Version = 1;
  357. Folders.Add(folder.ID, folder);
  358. folder = new InventoryFolderBase();
  359. folder.ParentID = rootFolder;
  360. folder.Owner = user;
  361. folder.ID = UUID.Random();
  362. folder.Name = "Photo Album";
  363. folder.Type = (short)AssetType.SnapshotFolder;
  364. folder.Version = 1;
  365. Folders.Add(folder.ID, folder);
  366. folder = new InventoryFolderBase();
  367. folder.ParentID = rootFolder;
  368. folder.Owner = user;
  369. folder.ID = UUID.Random();
  370. folder.Name = "Scripts";
  371. folder.Type = (short)AssetType.LSLText;
  372. folder.Version = 1;
  373. Folders.Add(folder.ID, folder);
  374. folder = new InventoryFolderBase();
  375. folder.ParentID = rootFolder;
  376. folder.Owner = user;
  377. folder.ID = UUID.Random();
  378. folder.Name = "Sounds";
  379. folder.Type = (short)AssetType.Sound;
  380. folder.Version = 1;
  381. Folders.Add(folder.ID, folder);
  382. folder = new InventoryFolderBase();
  383. folder.ParentID = rootFolder;
  384. folder.Owner = user;
  385. folder.ID = UUID.Random();
  386. folder.Name = "Textures";
  387. folder.Type = (short)AssetType.Texture;
  388. folder.Version = 1;
  389. Folders.Add(folder.ID, folder);
  390. folder = new InventoryFolderBase();
  391. folder.ParentID = rootFolder;
  392. folder.Owner = user;
  393. folder.ID = UUID.Random();
  394. folder.Name = "Trash";
  395. folder.Type = (short)AssetType.TrashFolder;
  396. folder.Version = 1;
  397. Folders.Add(folder.ID, folder);
  398. }
  399. }
  400. }
  401. }