aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/InventoryServiceBase.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Communications/InventoryServiceBase.cs255
1 files changed, 201 insertions, 54 deletions
diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs
index da7a0ce..6283b60 100644
--- a/OpenSim/Framework/Communications/InventoryServiceBase.cs
+++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs
@@ -1,4 +1,9 @@
1using System; 1using System;
2using System.Text;
3using System.IO;
4using System.Xml;
5using System.Xml.Serialization;
6using System.Collections;
2using System.Collections.Generic; 7using System.Collections.Generic;
3using System.Reflection; 8using System.Reflection;
4using libsecondlife; 9using libsecondlife;
@@ -6,21 +11,20 @@ using OpenSim.Framework.Communications;
6using OpenSim.Framework.Console; 11using OpenSim.Framework.Console;
7using OpenSim.Framework.Data; 12using OpenSim.Framework.Data;
8using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder; 13using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder;
14using InventoryCategory = OpenSim.Framework.Data.InventoryCategory;
9 15
10namespace OpenSim.Framework.Communications 16namespace OpenSim.Framework.Communications
11{ 17{
12 public abstract class InventoryServiceBase : IInventoryServices 18 public abstract class InventoryServiceBase : MarshalByRefObject, IInventoryServices
13 { 19 {
14 protected Dictionary<string, IInventoryData> m_plugins = new Dictionary<string, IInventoryData>(); 20 protected IInventoryData _databasePlugin;
15 //protected IAssetServer m_assetServer;
16 21
17 public InventoryServiceBase() 22 public InventoryServiceBase()
18 { 23 {
19 //m_assetServer = assetServer;
20 } 24 }
21 25
22 /// <summary> 26 /// <summary>
23 /// Adds a new user server plugin - plugins will be requested in the order they were loaded. 27 /// Adds a new inventory data server plugin
24 /// </summary> 28 /// </summary>
25 /// <param name="FileName">The filename to the user server plugin DLL</param> 29 /// <param name="FileName">The filename to the user server plugin DLL</param>
26 public void AddPlugin(string FileName) 30 public void AddPlugin(string FileName)
@@ -41,8 +45,13 @@ namespace OpenSim.Framework.Communications
41 IInventoryData plug = 45 IInventoryData plug =
42 (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); 46 (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
43 plug.Initialise(); 47 plug.Initialise();
44 this.m_plugins.Add(plug.getName(), plug); 48 this._databasePlugin = plug;
49
50 //TODO! find a better place to create inventory skeletons
51 loadInventoryFromXmlFile(InventoryCategory.Library, "Inventory_Library.xml");
52 loadInventoryFromXmlFile(InventoryCategory.Default, "Inventory_Default.xml");
45 MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface"); 53 MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface");
54 break;
46 } 55 }
47 } 56 }
48 } 57 }
@@ -54,20 +63,20 @@ namespace OpenSim.Framework.Communications
54 /// </summary> 63 /// </summary>
55 /// <param name="userID"></param> 64 /// <param name="userID"></param>
56 /// <returns></returns> 65 /// <returns></returns>
57 public List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID userID) 66 public List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID folderID)
58 { 67 {
59 List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>(); 68 InventoryFolderBase root = _databasePlugin.getInventoryFolder(folderID);
60 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) 69
70 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
71 if (root != null)
61 { 72 {
62 InventoryFolderBase rootFolder = plugin.Value.getUserRootFolder(userID); 73 folders.Add(root);
63 if (rootFolder != null) 74
64 { 75 List<InventoryFolderBase> subFolders = _databasePlugin.getInventoryFolders(root.folderID);
65 inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); 76 foreach (InventoryFolderBase f in subFolders)
66 inventoryList.Insert(0, rootFolder); 77 folders.Add(f);
67 return inventoryList;
68 }
69 } 78 }
70 return inventoryList; 79 return folders;
71 } 80 }
72 81
73 /// <summary> 82 /// <summary>
@@ -75,11 +84,7 @@ namespace OpenSim.Framework.Communications
75 /// </summary> 84 /// </summary>
76 public InventoryFolderBase RequestUsersRoot(LLUUID userID) 85 public InventoryFolderBase RequestUsersRoot(LLUUID userID)
77 { 86 {
78 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) 87 return _databasePlugin.getInventoryFolder(userID); // the id of the root folder, is the user id
79 {
80 return plugin.Value.getUserRootFolder(userID);
81 }
82 return null;
83 } 88 }
84 89
85 /// <summary> 90 /// <summary>
@@ -89,47 +94,27 @@ namespace OpenSim.Framework.Communications
89 /// <returns></returns> 94 /// <returns></returns>
90 public List<InventoryFolderBase> RequestSubFolders(LLUUID parentFolderID) 95 public List<InventoryFolderBase> RequestSubFolders(LLUUID parentFolderID)
91 { 96 {
92 List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>(); 97 return _databasePlugin.getInventoryFolders(parentFolderID);
93 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
94 {
95 return plugin.Value.getInventoryFolders(parentFolderID);
96 }
97 return inventoryList;
98 } 98 }
99 99
100 public List<InventoryItemBase> RequestFolderItems(LLUUID folderID) 100 public List<InventoryItemBase> RequestFolderItems(LLUUID folderID)
101 { 101 {
102 List<InventoryItemBase> itemsList = new List<InventoryItemBase>(); 102 return _databasePlugin.getInventoryInFolder(folderID);
103 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
104 {
105 itemsList = plugin.Value.getInventoryInFolder(folderID);
106 return itemsList;
107 }
108 return itemsList;
109 } 103 }
110 104
111 public void AddFolder(InventoryFolderBase folder) 105 public void AddFolder(InventoryFolderBase folder)
112 { 106 {
113 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) 107 _databasePlugin.addInventoryFolder(folder);
114 {
115 plugin.Value.addInventoryFolder(folder);
116 }
117 } 108 }
118 109
119 public void AddItem(InventoryItemBase item) 110 public void AddItem(InventoryItemBase item)
120 { 111 {
121 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) 112 _databasePlugin.addInventoryItem(item);
122 {
123 plugin.Value.addInventoryItem(item);
124 }
125 } 113 }
126 114
127 public void deleteItem(InventoryItemBase item) 115 public void deleteItem(InventoryItemBase item)
128 { 116 {
129 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) 117 _databasePlugin.deleteInventoryItem(item);
130 {
131 plugin.Value.deleteInventoryItem(item);
132 }
133 } 118 }
134 119
135 /// <summary> 120 /// <summary>
@@ -144,11 +129,53 @@ namespace OpenSim.Framework.Communications
144 } 129 }
145 } 130 }
146 131
147 public void CreateNewUserInventory(LLUUID user) 132 public void CreateNewUserInventory(LLUUID defaultFolders, LLUUID user)
148 { 133 {
149 UsersInventory inven = new UsersInventory(); 134 try
150 inven.CreateNewInventorySet(user); 135 {
151 this.AddNewInventorySet(inven); 136 // Get Default folder set from the database
137 //TODO! We need to get the whole hierachy and not just one level down
138 List<InventoryFolderBase> folders = this.RequestFirstLevelFolders(LLUUID.Parse("00000112-000f-0000-0000-000100bba000"));
139
140 // create an index list, where each of the elements has the index of its parent in the hierachy
141 // this algorithm is pretty shoddy O(n^2), but it is only executed once per user.
142 int[] parentIdx = new int[folders.Count];
143 for (int i = 0; i < folders.Count; i++)
144 parentIdx[i] = -1;
145
146 for (int i = 0; i < folders.Count; i++)
147 for (int j = 0; j < folders.Count; j++)
148 if (folders[i].folderID == folders[j].parentID)
149 parentIdx[j] = i;
150
151
152 //assign a new owerid and a new to the folders
153 foreach (InventoryFolderBase ifb in folders)
154 {
155 if (ifb.parentID == LLUUID.Zero)
156 ifb.folderID = user;
157 else
158 ifb.folderID = LLUUID.Random();
159
160 ifb.agentID = user;
161 ifb.category = InventoryCategory.User;
162 }
163
164 // correct the parent id
165 for (int i = 0; i < folders.Count; i++)
166 {
167 if (folders[i].parentID != LLUUID.Zero)
168 folders[i].parentID = folders[parentIdx[i]].folderID; // root folder id is the same as the user id
169 }
170
171 // the list is structurally sound, using new folder id's, so save it
172 foreach (InventoryFolderBase ifb in folders)
173 _databasePlugin.addInventoryFolder(ifb);
174 }
175 catch (Exception e)
176 {
177 MainLog.Instance.Error(e.ToString());
178 }
152 } 179 }
153 180
154 public class UsersInventory 181 public class UsersInventory
@@ -166,10 +193,11 @@ namespace OpenSim.Framework.Communications
166 InventoryFolderBase folder = new InventoryFolderBase(); 193 InventoryFolderBase folder = new InventoryFolderBase();
167 folder.parentID = LLUUID.Zero; 194 folder.parentID = LLUUID.Zero;
168 folder.agentID = user; 195 folder.agentID = user;
169 folder.folderID = LLUUID.Random(); 196 folder.folderID = user; // id of root folder is the same as the agent id
170 folder.name = "My Inventory"; 197 folder.name = "My Inventory";
171 folder.type = 8; 198 folder.type = 8;
172 folder.version = 1; 199 folder.version = 1;
200 folder.category = InventoryCategory.User;
173 Folders.Add(folder.folderID, folder); 201 Folders.Add(folder.folderID, folder);
174 202
175 LLUUID rootFolder = folder.folderID; 203 LLUUID rootFolder = folder.folderID;
@@ -181,6 +209,7 @@ namespace OpenSim.Framework.Communications
181 folder.name = "Textures"; 209 folder.name = "Textures";
182 folder.type = 0; 210 folder.type = 0;
183 folder.version = 1; 211 folder.version = 1;
212 folder.category = InventoryCategory.User;
184 Folders.Add(folder.folderID, folder); 213 Folders.Add(folder.folderID, folder);
185 214
186 folder = new InventoryFolderBase(); 215 folder = new InventoryFolderBase();
@@ -190,6 +219,7 @@ namespace OpenSim.Framework.Communications
190 folder.name = "Objects"; 219 folder.name = "Objects";
191 folder.type = 6; 220 folder.type = 6;
192 folder.version = 1; 221 folder.version = 1;
222 folder.category = InventoryCategory.User;
193 Folders.Add(folder.folderID, folder); 223 Folders.Add(folder.folderID, folder);
194 224
195 folder = new InventoryFolderBase(); 225 folder = new InventoryFolderBase();
@@ -199,13 +229,130 @@ namespace OpenSim.Framework.Communications
199 folder.name = "Clothes"; 229 folder.name = "Clothes";
200 folder.type = 5; 230 folder.type = 5;
201 folder.version = 1; 231 folder.version = 1;
232 folder.category = InventoryCategory.User;
202 Folders.Add(folder.folderID, folder); 233 Folders.Add(folder.folderID, folder);
203 } 234 }
204 } 235 }
205 236
237
238 public void GetRootFoldersForUser(LLUUID user, out LLUUID libraryFolder, out LLUUID personalFolder)
239 {
240 List<InventoryFolderBase> folders = _databasePlugin.getUserRootFolders(user);
241 libraryFolder = LLUUID.Zero;
242 personalFolder = LLUUID.Zero;
243
244 for (int i = 0; i < folders.Count; i++)
245 {
246 if (folders[i].category == InventoryCategory.Library)
247 libraryFolder = folders[i].folderID;
248 else if (folders[i].category == InventoryCategory.User)
249 personalFolder = folders[i].folderID;
250 }
251 }
252
253 /*
254 * Dot net has some issues, serializing a dictionary, so we cannot reuse the InventoryFolder
255 * class defined in Communications.Framework.Communications.Caches. So we serialize/deserialize
256 * into this simpler class, and then use that.
257 */
258 [XmlRoot(ElementName = "inventory", IsNullable = true)]
259 public class SerializedInventory
260 {
261 [XmlRoot(ElementName = "folder", IsNullable = true)]
262 public class SerializedFolder : InventoryFolderBase
263 {
264 [XmlArray(ElementName = "folders", IsNullable = true)]
265 [XmlArrayItem(ElementName = "folder", IsNullable = true, Type = typeof(SerializedFolder))]
266 public ArrayList SubFolders;
267
268 [XmlArray(ElementName = "items", IsNullable = true)]
269 [XmlArrayItem(ElementName = "item", IsNullable = true, Type = typeof(InventoryItemBase))]
270 public ArrayList Items;
271 }
272
273 [XmlElement(ElementName = "folder", IsNullable = true)]
274 public SerializedFolder root;
275 }
276
277 public void uploadInventory(SerializedInventory.SerializedFolder folder)
278 {
279 foreach (InventoryItemBase iib in folder.Items)
280 {
281 // assign default values, if they haven't assigned
282 iib.avatarID = folder.agentID;
283 if (iib.assetID == LLUUID.Zero)
284 iib.assetID = LLUUID.Random();
285 if (iib.creatorsID == LLUUID.Zero)
286 iib.creatorsID = folder.agentID;
287 if (iib.inventoryID == LLUUID.Zero)
288 iib.inventoryID = LLUUID.Random();
289 if (iib.inventoryName == null || iib.inventoryName.Length == 0)
290 iib.inventoryName = "new item";
291 iib.parentFolderID = folder.folderID;
292
293 _databasePlugin.addInventoryItem(iib);
294 }
295
296 foreach (SerializedInventory.SerializedFolder sf in folder.SubFolders)
297 {
298 // assign default values, if they haven't assigned
299 sf.agentID = folder.agentID;
300 sf.category = folder.category;
301 if (sf.folderID == LLUUID.Zero)
302 sf.folderID = LLUUID.Random();
303 if (sf.name == null || sf.name.Length == 0)
304 sf.name = "new folder";
305 sf.parentID = folder.folderID;
306
307 _databasePlugin.addInventoryFolder(sf);
308 uploadInventory(sf);
309 }
310 }
311
312 public void loadInventoryFromXmlFile(InventoryCategory inventoryCategory, string fileName)
313 {
314 _databasePlugin.deleteInventoryCategory(inventoryCategory);
315
316 FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
317 XmlReader reader = new XmlTextReader(fs);
318 XmlSerializer x = new XmlSerializer(typeof(SerializedInventory));
319 SerializedInventory inventory = (SerializedInventory)x.Deserialize(reader);
320
321 // the library and default inventories has no owner, so we use a random guid.
322 if (inventory.root.category == InventoryCategory.Library || inventory.root.category == InventoryCategory.Default)
323 {
324 if (inventory.root.folderID != LLUUID.Zero)
325 inventory.root.agentID = inventory.root.folderID;
326 else
327 inventory.root.agentID = LLUUID.Random();
328 }
329 else if (inventory.root.category == InventoryCategory.User)
330 {
331 if (inventory.root.agentID == LLUUID.Zero)
332 inventory.root.agentID = LLUUID.Random();
333 }
334
335 inventory.root.folderID = inventory.root.agentID; // the root folder always has the same id as the owning agent
336 inventory.root.parentID = LLUUID.Zero;
337 inventory.root.version = 0;
338 inventory.root.category = inventoryCategory;
339
340 _databasePlugin.addInventoryFolder(inventory.root);
341 uploadInventory(inventory.root);
342 }
343
344 protected void saveInventoryToXmlFile(SerializedInventory inventory, string fileName)
345 {
346 FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
347 XmlTextWriter writer = new XmlTextWriter(fs, Encoding.UTF8);
348 writer.Formatting = Formatting.Indented;
349 XmlSerializer x = new XmlSerializer(typeof(SerializedInventory));
350 x.Serialize(writer, inventory);
351 }
352
206 public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); 353 public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack);
207 public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder); 354 public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder);
208 public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); 355 public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item);
209 public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); 356 public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item);
210 } 357 }
211} \ No newline at end of file 358}