diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/InventoryFolderImpl.cs (renamed from OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs) | 936 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/ServiceConnectors/Inventory/HGInventoryBroker.cs | 366 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs | 246 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/ServiceConnectors/Inventory/RemoteInventoryServiceConnector.cs | 246 | ||||
-rw-r--r-- | OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs | 107 | ||||
-rw-r--r-- | OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs | 343 | ||||
-rw-r--r-- | OpenSim/Services/Interfaces/IInventoryService.cs | 118 | ||||
-rw-r--r-- | OpenSim/Services/InventoryService/HGInventoryService.cs | 178 | ||||
-rw-r--r-- | OpenSim/Services/InventoryService/InventoryService.cs | 544 | ||||
-rw-r--r-- | OpenSim/Services/InventoryService/InventoryServiceBase.cs | 98 | ||||
-rw-r--r-- | prebuild.xml | 31 |
11 files changed, 2743 insertions, 470 deletions
diff --git a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs b/OpenSim/Framework/InventoryFolderImpl.cs index 71f6f1b..248783f 100644 --- a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs +++ b/OpenSim/Framework/InventoryFolderImpl.cs | |||
@@ -1,470 +1,466 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using OpenMetaverse; | 30 | using OpenMetaverse; |
31 | 31 | ||
32 | //using System.Reflection; | 32 | namespace OpenSim.Framework |
33 | 33 | { | |
34 | //using log4net; | 34 | public class InventoryFolderImpl : InventoryFolderBase |
35 | 35 | { | |
36 | namespace OpenSim.Framework.Communications.Cache | 36 | //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
37 | { | 37 | |
38 | public class InventoryFolderImpl : InventoryFolderBase | 38 | public static readonly string PATH_DELIMITER = "/"; |
39 | { | 39 | |
40 | //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 40 | /// <summary> |
41 | 41 | /// Items that are contained in this folder | |
42 | public static readonly string PATH_DELIMITER = "/"; | 42 | /// </summary> |
43 | 43 | public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>(); | |
44 | /// <summary> | 44 | |
45 | /// Items that are contained in this folder | 45 | /// <summary> |
46 | /// </summary> | 46 | /// Child folders that are contained in this folder |
47 | public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>(); | 47 | /// </summary> |
48 | 48 | protected Dictionary<UUID, InventoryFolderImpl> m_childFolders = new Dictionary<UUID, InventoryFolderImpl>(); | |
49 | /// <summary> | 49 | |
50 | /// Child folders that are contained in this folder | 50 | // Constructors |
51 | /// </summary> | 51 | public InventoryFolderImpl(InventoryFolderBase folderbase) |
52 | protected Dictionary<UUID, InventoryFolderImpl> m_childFolders = new Dictionary<UUID, InventoryFolderImpl>(); | 52 | { |
53 | 53 | Owner = folderbase.Owner; | |
54 | // Constructors | 54 | ID = folderbase.ID; |
55 | public InventoryFolderImpl(InventoryFolderBase folderbase) | 55 | Name = folderbase.Name; |
56 | { | 56 | ParentID = folderbase.ParentID; |
57 | Owner = folderbase.Owner; | 57 | Type = folderbase.Type; |
58 | ID = folderbase.ID; | 58 | Version = folderbase.Version; |
59 | Name = folderbase.Name; | 59 | } |
60 | ParentID = folderbase.ParentID; | 60 | |
61 | Type = folderbase.Type; | 61 | public InventoryFolderImpl() |
62 | Version = folderbase.Version; | 62 | { |
63 | } | 63 | } |
64 | 64 | ||
65 | public InventoryFolderImpl() | 65 | /// <summary> |
66 | { | 66 | /// Create a new subfolder. |
67 | } | 67 | /// </summary> |
68 | 68 | /// <param name="folderID"></param> | |
69 | /// <summary> | 69 | /// <param name="folderName"></param> |
70 | /// Create a new subfolder. | 70 | /// <param name="type"></param> |
71 | /// </summary> | 71 | /// <returns>The newly created subfolder. Returns null if the folder already exists</returns> |
72 | /// <param name="folderID"></param> | 72 | public InventoryFolderImpl CreateChildFolder(UUID folderID, string folderName, ushort type) |
73 | /// <param name="folderName"></param> | 73 | { |
74 | /// <param name="type"></param> | 74 | lock (m_childFolders) |
75 | /// <returns>The newly created subfolder. Returns null if the folder already exists</returns> | 75 | { |
76 | public InventoryFolderImpl CreateChildFolder(UUID folderID, string folderName, ushort type) | 76 | if (!m_childFolders.ContainsKey(folderID)) |
77 | { | 77 | { |
78 | lock (m_childFolders) | 78 | InventoryFolderImpl subFold = new InventoryFolderImpl(); |
79 | { | 79 | subFold.Name = folderName; |
80 | if (!m_childFolders.ContainsKey(folderID)) | 80 | subFold.ID = folderID; |
81 | { | 81 | subFold.Type = (short)type; |
82 | InventoryFolderImpl subFold = new InventoryFolderImpl(); | 82 | subFold.ParentID = this.ID; |
83 | subFold.Name = folderName; | 83 | subFold.Owner = Owner; |
84 | subFold.ID = folderID; | 84 | m_childFolders.Add(subFold.ID, subFold); |
85 | subFold.Type = (short) type; | 85 | |
86 | subFold.ParentID = this.ID; | 86 | return subFold; |
87 | subFold.Owner = Owner; | 87 | } |
88 | m_childFolders.Add(subFold.ID, subFold); | 88 | } |
89 | 89 | ||
90 | return subFold; | 90 | return null; |
91 | } | 91 | } |
92 | } | 92 | |
93 | 93 | /// <summary> | |
94 | return null; | 94 | /// Add a folder that already exists. |
95 | } | 95 | /// </summary> |
96 | 96 | /// <param name="folder"></param> | |
97 | /// <summary> | 97 | public void AddChildFolder(InventoryFolderImpl folder) |
98 | /// Add a folder that already exists. | 98 | { |
99 | /// </summary> | 99 | lock (m_childFolders) |
100 | /// <param name="folder"></param> | 100 | { |
101 | public void AddChildFolder(InventoryFolderImpl folder) | 101 | folder.ParentID = ID; |
102 | { | 102 | m_childFolders[folder.ID] = folder; |
103 | lock (m_childFolders) | 103 | } |
104 | { | 104 | } |
105 | folder.ParentID = ID; | 105 | |
106 | m_childFolders[folder.ID] = folder; | 106 | /// <summary> |
107 | } | 107 | /// Does this folder contain the given child folder? |
108 | } | 108 | /// </summary> |
109 | 109 | /// <param name="folderID"></param> | |
110 | /// <summary> | 110 | /// <returns></returns> |
111 | /// Does this folder contain the given child folder? | 111 | public bool ContainsChildFolder(UUID folderID) |
112 | /// </summary> | 112 | { |
113 | /// <param name="folderID"></param> | 113 | return m_childFolders.ContainsKey(folderID); |
114 | /// <returns></returns> | 114 | } |
115 | public bool ContainsChildFolder(UUID folderID) | 115 | |
116 | { | 116 | /// <summary> |
117 | return m_childFolders.ContainsKey(folderID); | 117 | /// Get a child folder |
118 | } | 118 | /// </summary> |
119 | 119 | /// <param name="folderID"></param> | |
120 | /// <summary> | 120 | /// <returns>The folder if it exists, null if it doesn't</returns> |
121 | /// Get a child folder | 121 | public InventoryFolderImpl GetChildFolder(UUID folderID) |
122 | /// </summary> | 122 | { |
123 | /// <param name="folderID"></param> | 123 | InventoryFolderImpl folder = null; |
124 | /// <returns>The folder if it exists, null if it doesn't</returns> | 124 | |
125 | public InventoryFolderImpl GetChildFolder(UUID folderID) | 125 | lock (m_childFolders) |
126 | { | 126 | { |
127 | InventoryFolderImpl folder = null; | 127 | m_childFolders.TryGetValue(folderID, out folder); |
128 | 128 | } | |
129 | lock (m_childFolders) | 129 | |
130 | { | 130 | return folder; |
131 | m_childFolders.TryGetValue(folderID, out folder); | 131 | } |
132 | } | 132 | |
133 | 133 | /// <summary> | |
134 | return folder; | 134 | /// Removes the given child subfolder. |
135 | } | 135 | /// </summary> |
136 | 136 | /// <param name="folderID"></param> | |
137 | /// <summary> | 137 | /// <returns> |
138 | /// Removes the given child subfolder. | 138 | /// The folder removed, or null if the folder was not present. |
139 | /// </summary> | 139 | /// </returns> |
140 | /// <param name="folderID"></param> | 140 | public InventoryFolderImpl RemoveChildFolder(UUID folderID) |
141 | /// <returns> | 141 | { |
142 | /// The folder removed, or null if the folder was not present. | 142 | InventoryFolderImpl removedFolder = null; |
143 | /// </returns> | 143 | |
144 | public InventoryFolderImpl RemoveChildFolder(UUID folderID) | 144 | lock (m_childFolders) |
145 | { | 145 | { |
146 | InventoryFolderImpl removedFolder = null; | 146 | if (m_childFolders.ContainsKey(folderID)) |
147 | 147 | { | |
148 | lock (m_childFolders) | 148 | removedFolder = m_childFolders[folderID]; |
149 | { | 149 | m_childFolders.Remove(folderID); |
150 | if (m_childFolders.ContainsKey(folderID)) | 150 | } |
151 | { | 151 | } |
152 | removedFolder = m_childFolders[folderID]; | 152 | |
153 | m_childFolders.Remove(folderID); | 153 | return removedFolder; |
154 | } | 154 | } |
155 | } | 155 | |
156 | 156 | /// <summary> | |
157 | return removedFolder; | 157 | /// Delete all the folders and items in this folder. |
158 | } | 158 | /// </summary> |
159 | 159 | public void Purge() | |
160 | /// <summary> | 160 | { |
161 | /// Delete all the folders and items in this folder. | 161 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
162 | /// </summary> | 162 | { |
163 | public void Purge() | 163 | folder.Purge(); |
164 | { | 164 | } |
165 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 165 | |
166 | { | 166 | m_childFolders.Clear(); |
167 | folder.Purge(); | 167 | Items.Clear(); |
168 | } | 168 | } |
169 | 169 | ||
170 | m_childFolders.Clear(); | 170 | /// <summary> |
171 | Items.Clear(); | 171 | /// Returns the item if it exists in this folder or in any of this folder's descendant folders |
172 | } | 172 | /// </summary> |
173 | 173 | /// <param name="itemID"></param> | |
174 | /// <summary> | 174 | /// <returns>null if the item is not found</returns> |
175 | /// Returns the item if it exists in this folder or in any of this folder's descendant folders | 175 | public InventoryItemBase FindItem(UUID itemID) |
176 | /// </summary> | 176 | { |
177 | /// <param name="itemID"></param> | 177 | lock (Items) |
178 | /// <returns>null if the item is not found</returns> | 178 | { |
179 | public InventoryItemBase FindItem(UUID itemID) | 179 | if (Items.ContainsKey(itemID)) |
180 | { | 180 | { |
181 | lock (Items) | 181 | return Items[itemID]; |
182 | { | 182 | } |
183 | if (Items.ContainsKey(itemID)) | 183 | } |
184 | { | 184 | |
185 | return Items[itemID]; | 185 | lock (m_childFolders) |
186 | } | 186 | { |
187 | } | 187 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
188 | 188 | { | |
189 | lock (m_childFolders) | 189 | InventoryItemBase item = folder.FindItem(itemID); |
190 | { | 190 | |
191 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 191 | if (item != null) |
192 | { | 192 | { |
193 | InventoryItemBase item = folder.FindItem(itemID); | 193 | return item; |
194 | 194 | } | |
195 | if (item != null) | 195 | } |
196 | { | 196 | } |
197 | return item; | 197 | |
198 | } | 198 | return null; |
199 | } | 199 | } |
200 | } | 200 | |
201 | 201 | public InventoryItemBase FindAsset(UUID assetID) | |
202 | return null; | 202 | { |
203 | } | 203 | lock (Items) |
204 | 204 | { | |
205 | public InventoryItemBase FindAsset(UUID assetID) | 205 | foreach (InventoryItemBase item in Items.Values) |
206 | { | 206 | { |
207 | lock (Items) | 207 | if (item.AssetID == assetID) |
208 | { | 208 | return item; |
209 | foreach (InventoryItemBase item in Items.Values) | 209 | } |
210 | { | 210 | } |
211 | if (item.AssetID == assetID) | 211 | |
212 | return item; | 212 | lock (m_childFolders) |
213 | } | 213 | { |
214 | } | 214 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
215 | 215 | { | |
216 | lock (m_childFolders) | 216 | InventoryItemBase item = folder.FindAsset(assetID); |
217 | { | 217 | |
218 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 218 | if (item != null) |
219 | { | 219 | { |
220 | InventoryItemBase item = folder.FindAsset(assetID); | 220 | return item; |
221 | 221 | } | |
222 | if (item != null) | 222 | } |
223 | { | 223 | } |
224 | return item; | 224 | |
225 | } | 225 | return null; |
226 | } | 226 | } |
227 | } | 227 | |
228 | 228 | /// <summary> | |
229 | return null; | 229 | /// Deletes an item if it exists in this folder or any children |
230 | } | 230 | /// </summary> |
231 | 231 | /// <param name="folderID"></param> | |
232 | /// <summary> | 232 | /// <returns></returns> |
233 | /// Deletes an item if it exists in this folder or any children | 233 | public bool DeleteItem(UUID itemID) |
234 | /// </summary> | 234 | { |
235 | /// <param name="folderID"></param> | 235 | bool found = false; |
236 | /// <returns></returns> | 236 | |
237 | public bool DeleteItem(UUID itemID) | 237 | lock (Items) |
238 | { | 238 | { |
239 | bool found = false; | 239 | if (Items.ContainsKey(itemID)) |
240 | 240 | { | |
241 | lock (Items) | 241 | Items.Remove(itemID); |
242 | { | 242 | return true; |
243 | if (Items.ContainsKey(itemID)) | 243 | } |
244 | { | 244 | } |
245 | Items.Remove(itemID); | 245 | |
246 | return true; | 246 | lock (m_childFolders) |
247 | } | 247 | { |
248 | } | 248 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
249 | 249 | { | |
250 | lock (m_childFolders) | 250 | found = folder.DeleteItem(itemID); |
251 | { | 251 | |
252 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 252 | if (found == true) |
253 | { | 253 | { |
254 | found = folder.DeleteItem(itemID); | 254 | break; |
255 | 255 | } | |
256 | if (found == true) | 256 | } |
257 | { | 257 | } |
258 | break; | 258 | |
259 | } | 259 | return found; |
260 | } | 260 | } |
261 | } | 261 | |
262 | 262 | /// <summary> | |
263 | return found; | 263 | /// Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth |
264 | } | 264 | /// first. |
265 | 265 | /// </summary> | |
266 | /// <summary> | 266 | /// <returns>The requested folder if it exists, null if it does not.</returns> |
267 | /// Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth | 267 | public InventoryFolderImpl FindFolder(UUID folderID) |
268 | /// first. | 268 | { |
269 | /// </summary> | 269 | if (folderID == ID) |
270 | /// <returns>The requested folder if it exists, null if it does not.</returns> | 270 | return this; |
271 | public InventoryFolderImpl FindFolder(UUID folderID) | 271 | |
272 | { | 272 | lock (m_childFolders) |
273 | if (folderID == ID) | 273 | { |
274 | return this; | 274 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
275 | 275 | { | |
276 | lock (m_childFolders) | 276 | InventoryFolderImpl returnFolder = folder.FindFolder(folderID); |
277 | { | 277 | |
278 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 278 | if (returnFolder != null) |
279 | { | 279 | return returnFolder; |
280 | InventoryFolderImpl returnFolder = folder.FindFolder(folderID); | 280 | } |
281 | 281 | } | |
282 | if (returnFolder != null) | 282 | |
283 | return returnFolder; | 283 | return null; |
284 | } | 284 | } |
285 | } | 285 | |
286 | 286 | /// <summary> | |
287 | return null; | 287 | /// Look through all child subfolders for a folder marked as one for a particular asset type, and return it. |
288 | } | 288 | /// </summary> |
289 | 289 | /// <param name="type"></param> | |
290 | /// <summary> | 290 | /// <returns>Returns null if no such folder is found</returns> |
291 | /// Look through all child subfolders for a folder marked as one for a particular asset type, and return it. | 291 | public InventoryFolderImpl FindFolderForType(int type) |
292 | /// </summary> | 292 | { |
293 | /// <param name="type"></param> | 293 | lock (m_childFolders) |
294 | /// <returns>Returns null if no such folder is found</returns> | 294 | { |
295 | public InventoryFolderImpl FindFolderForType(int type) | 295 | foreach (InventoryFolderImpl f in m_childFolders.Values) |
296 | { | 296 | { |
297 | lock (m_childFolders) | 297 | if (f.Type == type) |
298 | { | 298 | return f; |
299 | foreach (InventoryFolderImpl f in m_childFolders.Values) | 299 | } |
300 | { | 300 | } |
301 | if (f.Type == type) | 301 | |
302 | return f; | 302 | return null; |
303 | } | 303 | } |
304 | } | 304 | |
305 | 305 | /// <summary> | |
306 | return null; | 306 | /// Find a folder given a PATH_DELIMITER delimited path starting from this folder |
307 | } | 307 | /// </summary> |
308 | 308 | /// | |
309 | /// <summary> | 309 | /// This method does not handle paths that contain multiple delimitors |
310 | /// Find a folder given a PATH_DELIMITER delimited path starting from this folder | 310 | /// |
311 | /// </summary> | 311 | /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some |
312 | /// | 312 | /// XPath like expression |
313 | /// This method does not handle paths that contain multiple delimitors | 313 | /// |
314 | /// | 314 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. |
315 | /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some | 315 | /// |
316 | /// XPath like expression | 316 | /// <param name="path"> |
317 | /// | 317 | /// The path to the required folder. |
318 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | 318 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. |
319 | /// | 319 | /// </param> |
320 | /// <param name="path"> | 320 | /// <returns>null if the folder is not found</returns> |
321 | /// The path to the required folder. | 321 | public InventoryFolderImpl FindFolderByPath(string path) |
322 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. | 322 | { |
323 | /// </param> | 323 | if (path == string.Empty) |
324 | /// <returns>null if the folder is not found</returns> | 324 | return this; |
325 | public InventoryFolderImpl FindFolderByPath(string path) | 325 | |
326 | { | 326 | path = path.Trim(); |
327 | if (path == string.Empty) | 327 | |
328 | return this; | 328 | if (path == PATH_DELIMITER) |
329 | 329 | return this; | |
330 | path = path.Trim(); | 330 | |
331 | 331 | string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); | |
332 | if (path == PATH_DELIMITER) | 332 | |
333 | return this; | 333 | lock (m_childFolders) |
334 | 334 | { | |
335 | string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); | 335 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
336 | 336 | { | |
337 | lock (m_childFolders) | 337 | if (folder.Name == components[0]) |
338 | { | 338 | if (components.Length > 1) |
339 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 339 | return folder.FindFolderByPath(components[1]); |
340 | { | 340 | else |
341 | if (folder.Name == components[0]) | 341 | return folder; |
342 | if (components.Length > 1) | 342 | } |
343 | return folder.FindFolderByPath(components[1]); | 343 | } |
344 | else | 344 | |
345 | return folder; | 345 | // We didn't find a folder with the given name |
346 | } | 346 | return null; |
347 | } | 347 | } |
348 | 348 | ||
349 | // We didn't find a folder with the given name | 349 | /// <summary> |
350 | return null; | 350 | /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. |
351 | } | 351 | /// |
352 | 352 | /// This method does not handle paths that contain multiple delimitors | |
353 | /// <summary> | 353 | /// |
354 | /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. | 354 | /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some |
355 | /// | 355 | /// XPath like expression |
356 | /// This method does not handle paths that contain multiple delimitors | 356 | /// |
357 | /// | 357 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. |
358 | /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some | 358 | /// </summary> |
359 | /// XPath like expression | 359 | /// <param name="path"> |
360 | /// | 360 | /// The path to the required item. |
361 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | 361 | /// </param> |
362 | /// </summary> | 362 | /// <returns>null if the item is not found</returns> |
363 | /// <param name="path"> | 363 | public InventoryItemBase FindItemByPath(string path) |
364 | /// The path to the required item. | 364 | { |
365 | /// </param> | 365 | string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); |
366 | /// <returns>null if the item is not found</returns> | 366 | |
367 | public InventoryItemBase FindItemByPath(string path) | 367 | if (components.Length == 1) |
368 | { | 368 | { |
369 | string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); | 369 | lock (Items) |
370 | 370 | { | |
371 | if (components.Length == 1) | 371 | foreach (InventoryItemBase item in Items.Values) |
372 | { | 372 | { |
373 | lock (Items) | 373 | if (item.Name == components[0]) |
374 | { | 374 | return item; |
375 | foreach (InventoryItemBase item in Items.Values) | 375 | } |
376 | { | 376 | } |
377 | if (item.Name == components[0]) | 377 | } |
378 | return item; | 378 | else |
379 | } | 379 | { |
380 | } | 380 | lock (m_childFolders) |
381 | } | 381 | { |
382 | else | 382 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
383 | { | 383 | { |
384 | lock (m_childFolders) | 384 | if (folder.Name == components[0]) |
385 | { | 385 | return folder.FindItemByPath(components[1]); |
386 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 386 | } |
387 | { | 387 | } |
388 | if (folder.Name == components[0]) | 388 | } |
389 | return folder.FindItemByPath(components[1]); | 389 | |
390 | } | 390 | // We didn't find an item or intermediate folder with the given name |
391 | } | 391 | return null; |
392 | } | 392 | } |
393 | 393 | ||
394 | // We didn't find an item or intermediate folder with the given name | 394 | /// <summary> |
395 | return null; | 395 | /// Return a copy of the list of child items in this folder. The items themselves are the originals. |
396 | } | 396 | /// </summary> |
397 | 397 | public List<InventoryItemBase> RequestListOfItems() | |
398 | /// <summary> | 398 | { |
399 | /// Return a copy of the list of child items in this folder. The items themselves are the originals. | 399 | List<InventoryItemBase> itemList = new List<InventoryItemBase>(); |
400 | /// </summary> | 400 | |
401 | public List<InventoryItemBase> RequestListOfItems() | 401 | lock (Items) |
402 | { | 402 | { |
403 | List<InventoryItemBase> itemList = new List<InventoryItemBase>(); | 403 | foreach (InventoryItemBase item in Items.Values) |
404 | 404 | { | |
405 | lock (Items) | 405 | itemList.Add(item); |
406 | { | 406 | } |
407 | foreach (InventoryItemBase item in Items.Values) | 407 | } |
408 | { | 408 | |
409 | itemList.Add(item); | 409 | //m_log.DebugFormat("[INVENTORY FOLDER IMPL]: Found {0} items", itemList.Count); |
410 | } | 410 | |
411 | } | 411 | return itemList; |
412 | 412 | } | |
413 | //m_log.DebugFormat("[INVENTORY FOLDER IMPL]: Found {0} items", itemList.Count); | 413 | |
414 | 414 | /// <summary> | |
415 | return itemList; | 415 | /// Return a copy of the list of child folders in this folder. The folders themselves are the originals. |
416 | } | 416 | /// </summary> |
417 | 417 | public List<InventoryFolderBase> RequestListOfFolders() | |
418 | /// <summary> | 418 | { |
419 | /// Return a copy of the list of child folders in this folder. The folders themselves are the originals. | 419 | List<InventoryFolderBase> folderList = new List<InventoryFolderBase>(); |
420 | /// </summary> | 420 | |
421 | public List<InventoryFolderBase> RequestListOfFolders() | 421 | lock (m_childFolders) |
422 | { | 422 | { |
423 | List<InventoryFolderBase> folderList = new List<InventoryFolderBase>(); | 423 | foreach (InventoryFolderBase folder in m_childFolders.Values) |
424 | 424 | { | |
425 | lock (m_childFolders) | 425 | folderList.Add(folder); |
426 | { | 426 | } |
427 | foreach (InventoryFolderBase folder in m_childFolders.Values) | 427 | } |
428 | { | 428 | |
429 | folderList.Add(folder); | 429 | return folderList; |
430 | } | 430 | } |
431 | } | 431 | |
432 | 432 | public List<InventoryFolderImpl> RequestListOfFolderImpls() | |
433 | return folderList; | 433 | { |
434 | } | 434 | List<InventoryFolderImpl> folderList = new List<InventoryFolderImpl>(); |
435 | 435 | ||
436 | public List<InventoryFolderImpl> RequestListOfFolderImpls() | 436 | lock (m_childFolders) |
437 | { | 437 | { |
438 | List<InventoryFolderImpl> folderList = new List<InventoryFolderImpl>(); | 438 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
439 | 439 | { | |
440 | lock (m_childFolders) | 440 | folderList.Add(folder); |
441 | { | 441 | } |
442 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 442 | } |
443 | { | 443 | |
444 | folderList.Add(folder); | 444 | return folderList; |
445 | } | 445 | } |
446 | } | 446 | |
447 | 447 | /// <value> | |
448 | return folderList; | 448 | /// The total number of items in this folder and in the immediate child folders (though not from other |
449 | } | 449 | /// descendants). |
450 | 450 | /// </value> | |
451 | /// <value> | 451 | public int TotalCount |
452 | /// The total number of items in this folder and in the immediate child folders (though not from other | 452 | { |
453 | /// descendants). | 453 | get |
454 | /// </value> | 454 | { |
455 | public int TotalCount | 455 | int total = Items.Count; |
456 | { | 456 | |
457 | get | 457 | foreach (InventoryFolderImpl folder in m_childFolders.Values) |
458 | { | 458 | { |
459 | int total = Items.Count; | 459 | total = total + folder.TotalCount; |
460 | 460 | } | |
461 | foreach (InventoryFolderImpl folder in m_childFolders.Values) | 461 | |
462 | { | 462 | return total; |
463 | total = total + folder.TotalCount; | 463 | } |
464 | } | 464 | } |
465 | 465 | } | |
466 | return total; | 466 | } |
467 | } | ||
468 | } | ||
469 | } | ||
470 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/HGInventoryBroker.cs new file mode 100644 index 0000000..f4cd269 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/HGInventoryBroker.cs | |||
@@ -0,0 +1,366 @@ | |||
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 | |||
28 | using log4net; | ||
29 | using Nini.Config; | ||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Reflection; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Communications.Cache; | ||
35 | using OpenSim.Server.Base; | ||
36 | using OpenSim.Region.Framework.Interfaces; | ||
37 | using OpenSim.Region.Framework.Scenes; | ||
38 | using OpenSim.Services.Interfaces; | ||
39 | using OpenSim.Services.Connectors; | ||
40 | using OpenMetaverse; | ||
41 | |||
42 | namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory | ||
43 | { | ||
44 | public class HGInventoryBroker : ISharedRegionModule, IInventoryService | ||
45 | { | ||
46 | private static readonly ILog m_log = | ||
47 | LogManager.GetLogger( | ||
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private bool m_Enabled = false; | ||
51 | private bool m_Initialized = false; | ||
52 | private Scene m_Scene; | ||
53 | private UserProfileCacheService m_UserProfileService; // This should change to IUserProfileService | ||
54 | |||
55 | private IInventoryService m_GridService; | ||
56 | private ISessionAuthInventoryService m_HGService; | ||
57 | |||
58 | private string m_LocalGridInventoryURI = string.Empty; | ||
59 | public string Name | ||
60 | { | ||
61 | get { return "HGInventoryBroker"; } | ||
62 | } | ||
63 | |||
64 | public void Initialise(IConfigSource source) | ||
65 | { | ||
66 | IConfig moduleConfig = source.Configs["Modules"]; | ||
67 | if (moduleConfig != null) | ||
68 | { | ||
69 | string name = moduleConfig.GetString("InventoryServices", ""); | ||
70 | if (name == Name) | ||
71 | { | ||
72 | IConfig inventoryConfig = source.Configs["InventoryService"]; | ||
73 | if (inventoryConfig == null) | ||
74 | { | ||
75 | m_log.Error("[HG INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | string localDll = inventoryConfig.GetString("LocalGridInventoryService", | ||
80 | String.Empty); | ||
81 | string HGDll = inventoryConfig.GetString("HypergridInventoryService", | ||
82 | String.Empty); | ||
83 | |||
84 | if (localDll == String.Empty) | ||
85 | { | ||
86 | m_log.Error("[HG INVENTORY CONNECTOR]: No LocalGridInventoryService named in section InventoryService"); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | if (HGDll == String.Empty) | ||
91 | { | ||
92 | m_log.Error("[HG INVENTORY CONNECTOR]: No HypergridInventoryService named in section InventoryService"); | ||
93 | return; | ||
94 | } | ||
95 | |||
96 | Object[] args = new Object[] { source }; | ||
97 | m_GridService = | ||
98 | ServerUtils.LoadPlugin<IInventoryService>(localDll, | ||
99 | args); | ||
100 | |||
101 | m_HGService = | ||
102 | ServerUtils.LoadPlugin<ISessionAuthInventoryService>(HGDll, | ||
103 | args); | ||
104 | |||
105 | if (m_GridService == null) | ||
106 | { | ||
107 | m_log.Error("[HG INVENTORY CONNECTOR]: Can't load local inventory service"); | ||
108 | return; | ||
109 | } | ||
110 | if (m_HGService == null) | ||
111 | { | ||
112 | m_log.Error("[HG INVENTORY CONNECTOR]: Can't load hypergrid inventory service"); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | m_LocalGridInventoryURI = inventoryConfig.GetString("InventoryServerURI", string.Empty); | ||
117 | |||
118 | m_Enabled = true; | ||
119 | m_log.Info("[HG INVENTORY CONNECTOR]: HG asset broker enabled"); | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | public void PostInitialise() | ||
125 | { | ||
126 | } | ||
127 | |||
128 | public void Close() | ||
129 | { | ||
130 | } | ||
131 | |||
132 | public void AddRegion(Scene scene) | ||
133 | { | ||
134 | if (!m_Enabled) | ||
135 | return; | ||
136 | |||
137 | if (!m_Initialized) | ||
138 | { | ||
139 | m_Scene = scene; | ||
140 | // HACK for now. Ugh! | ||
141 | m_UserProfileService = m_Scene.CommsManager.UserProfileCacheService; | ||
142 | } | ||
143 | |||
144 | scene.RegisterModuleInterface<IInventoryService>(this); | ||
145 | } | ||
146 | |||
147 | public void RemoveRegion(Scene scene) | ||
148 | { | ||
149 | } | ||
150 | |||
151 | public void RegionLoaded(Scene scene) | ||
152 | { | ||
153 | if (!m_Enabled) | ||
154 | return; | ||
155 | |||
156 | m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled remote inventory for region {0}", scene.RegionInfo.RegionName); | ||
157 | |||
158 | } | ||
159 | |||
160 | #region IInventoryService | ||
161 | |||
162 | public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) | ||
163 | { | ||
164 | if (IsLocalGridUser(userID)) | ||
165 | m_GridService.GetUserInventory(userID, callback); | ||
166 | else | ||
167 | { | ||
168 | UUID sessionID = GetSessionID(userID); | ||
169 | string uri = "http://" + GetUserInventoryURI(userID) + "/" + userID.ToString(); | ||
170 | m_HGService.GetUserInventory(uri, sessionID, callback); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | public bool AddFolder(InventoryFolderBase folder) | ||
175 | { | ||
176 | if (folder == null) | ||
177 | return false; | ||
178 | |||
179 | if (IsLocalGridUser(folder.Owner)) | ||
180 | return m_GridService.AddFolder(folder); | ||
181 | else | ||
182 | { | ||
183 | UUID sessionID = GetSessionID(folder.Owner); | ||
184 | string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); | ||
185 | return m_HGService.AddFolder(uri, folder, sessionID); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | public bool UpdateFolder(InventoryFolderBase folder) | ||
190 | { | ||
191 | if (folder == null) | ||
192 | return false; | ||
193 | |||
194 | if (IsLocalGridUser(folder.Owner)) | ||
195 | return m_GridService.UpdateFolder(folder); | ||
196 | else | ||
197 | { | ||
198 | UUID sessionID = GetSessionID(folder.Owner); | ||
199 | string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); | ||
200 | return m_HGService.UpdateFolder(uri, folder, sessionID); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | public bool MoveFolder(InventoryFolderBase folder) | ||
205 | { | ||
206 | if (folder == null) | ||
207 | return false; | ||
208 | |||
209 | if (IsLocalGridUser(folder.Owner)) | ||
210 | return m_GridService.MoveFolder(folder); | ||
211 | else | ||
212 | { | ||
213 | UUID sessionID = GetSessionID(folder.Owner); | ||
214 | string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); | ||
215 | return m_HGService.MoveFolder(uri, folder, sessionID); | ||
216 | } | ||
217 | } | ||
218 | |||
219 | public bool PurgeFolder(InventoryFolderBase folder) | ||
220 | { | ||
221 | if (folder == null) | ||
222 | return false; | ||
223 | |||
224 | if (IsLocalGridUser(folder.Owner)) | ||
225 | return m_GridService.PurgeFolder(folder); | ||
226 | else | ||
227 | { | ||
228 | UUID sessionID = GetSessionID(folder.Owner); | ||
229 | string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); | ||
230 | return m_HGService.PurgeFolder(uri, folder, sessionID); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | public bool AddItem(InventoryItemBase item) | ||
235 | { | ||
236 | if (item == null) | ||
237 | return false; | ||
238 | |||
239 | if (IsLocalGridUser(item.Owner)) | ||
240 | return m_GridService.AddItem(item); | ||
241 | else | ||
242 | { | ||
243 | UUID sessionID = GetSessionID(item.Owner); | ||
244 | string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); | ||
245 | return m_HGService.AddItem(uri, item, sessionID); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | public bool UpdateItem(InventoryItemBase item) | ||
250 | { | ||
251 | if (item == null) | ||
252 | return false; | ||
253 | |||
254 | if (IsLocalGridUser(item.Owner)) | ||
255 | return m_GridService.UpdateItem(item); | ||
256 | else | ||
257 | { | ||
258 | UUID sessionID = GetSessionID(item.Owner); | ||
259 | string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); | ||
260 | return m_HGService.UpdateItem(uri, item, sessionID); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | public bool DeleteItem(InventoryItemBase item) | ||
265 | { | ||
266 | if (item == null) | ||
267 | return false; | ||
268 | |||
269 | if (IsLocalGridUser(item.Owner)) | ||
270 | return m_GridService.DeleteItem(item); | ||
271 | else | ||
272 | { | ||
273 | UUID sessionID = GetSessionID(item.Owner); | ||
274 | string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); | ||
275 | return m_HGService.DeleteItem(uri, item, sessionID); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | public InventoryItemBase QueryItem(InventoryItemBase item) | ||
280 | { | ||
281 | if (item == null) | ||
282 | return null; | ||
283 | |||
284 | if (IsLocalGridUser(item.Owner)) | ||
285 | return m_GridService.QueryItem(item); | ||
286 | else | ||
287 | { | ||
288 | UUID sessionID = GetSessionID(item.Owner); | ||
289 | string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); | ||
290 | return m_HGService.QueryItem(uri, item, sessionID); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | public InventoryFolderBase QueryFolder(InventoryFolderBase folder) | ||
295 | { | ||
296 | if (folder == null) | ||
297 | return null; | ||
298 | |||
299 | if (IsLocalGridUser(folder.Owner)) | ||
300 | return m_GridService.QueryFolder(folder); | ||
301 | else | ||
302 | { | ||
303 | UUID sessionID = GetSessionID(folder.Owner); | ||
304 | string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); | ||
305 | return m_HGService.QueryFolder(uri, folder, sessionID); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | public bool HasInventoryForUser(UUID userID) | ||
310 | { | ||
311 | return false; | ||
312 | } | ||
313 | |||
314 | public InventoryFolderBase RequestRootFolder(UUID userID) | ||
315 | { | ||
316 | return null; | ||
317 | } | ||
318 | |||
319 | #endregion | ||
320 | |||
321 | private UUID GetSessionID(UUID userID) | ||
322 | { | ||
323 | ScenePresence sp = m_Scene.GetScenePresence(userID); | ||
324 | if (sp != null) | ||
325 | return sp.ControllingClient.SessionId; | ||
326 | |||
327 | return UUID.Zero; | ||
328 | } | ||
329 | |||
330 | private bool IsLocalGridUser(UUID userID) | ||
331 | { | ||
332 | if (m_UserProfileService == null) | ||
333 | return false; | ||
334 | |||
335 | CachedUserInfo uinfo = m_UserProfileService.GetUserDetails(userID); | ||
336 | if (uinfo == null) | ||
337 | return true; | ||
338 | |||
339 | string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI); | ||
340 | |||
341 | if ((userInventoryServerURI == m_LocalGridInventoryURI) || (userInventoryServerURI == "")) | ||
342 | { | ||
343 | return true; | ||
344 | } | ||
345 | return false; | ||
346 | } | ||
347 | |||
348 | private string GetUserInventoryURI(UUID userID) | ||
349 | { | ||
350 | string invURI = m_LocalGridInventoryURI; | ||
351 | |||
352 | CachedUserInfo uinfo = m_UserProfileService.GetUserDetails(userID); | ||
353 | if ((uinfo == null) || (uinfo.UserProfile == null)) | ||
354 | return invURI; | ||
355 | |||
356 | string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI); | ||
357 | |||
358 | if ((userInventoryServerURI != null) && | ||
359 | (userInventoryServerURI != "")) | ||
360 | invURI = userInventoryServerURI; | ||
361 | return invURI; | ||
362 | } | ||
363 | |||
364 | |||
365 | } | ||
366 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs new file mode 100644 index 0000000..3db08eb --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs | |||
@@ -0,0 +1,246 @@ | |||
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 | |||
28 | using log4net; | ||
29 | using Nini.Config; | ||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Reflection; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Data; | ||
35 | using OpenSim.Server.Base; | ||
36 | using OpenSim.Region.Framework.Interfaces; | ||
37 | using OpenSim.Region.Framework.Scenes; | ||
38 | using OpenSim.Services.Interfaces; | ||
39 | using OpenMetaverse; | ||
40 | |||
41 | namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory | ||
42 | { | ||
43 | public class LocalInventoryServicesConnector : | ||
44 | ISharedRegionModule, IInventoryService | ||
45 | { | ||
46 | private static readonly ILog m_log = | ||
47 | LogManager.GetLogger( | ||
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private IInventoryService m_InventoryService; | ||
51 | |||
52 | private bool m_Enabled = false; | ||
53 | |||
54 | public string Name | ||
55 | { | ||
56 | get { return "LocalInventoryServicesConnector"; } | ||
57 | } | ||
58 | |||
59 | public void Initialise(IConfigSource source) | ||
60 | { | ||
61 | IConfig moduleConfig = source.Configs["Modules"]; | ||
62 | if (moduleConfig != null) | ||
63 | { | ||
64 | string name = moduleConfig.GetString("InventoryServices", ""); | ||
65 | if (name == Name) | ||
66 | { | ||
67 | IConfig assetConfig = source.Configs["InventoryService"]; | ||
68 | if (assetConfig == null) | ||
69 | { | ||
70 | m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | string serviceDll = assetConfig.GetString("LocalServiceModule", | ||
75 | String.Empty); | ||
76 | |||
77 | if (serviceDll == String.Empty) | ||
78 | { | ||
79 | m_log.Error("[INVENTORY CONNECTOR]: No LocalServiceModule named in section InventoryService"); | ||
80 | return; | ||
81 | } | ||
82 | |||
83 | Object[] args = new Object[] { source }; | ||
84 | m_InventoryService = | ||
85 | ServerUtils.LoadPlugin<IInventoryService>(serviceDll, | ||
86 | args); | ||
87 | |||
88 | if (m_InventoryService == null) | ||
89 | { | ||
90 | m_log.Error("[INVENTORY CONNECTOR]: Can't load asset service"); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | //List<IInventoryDataPlugin> plugins | ||
95 | // = DataPluginFactory.LoadDataPlugins<IInventoryDataPlugin>( | ||
96 | // configSettings.StandaloneInventoryPlugin, | ||
97 | // configSettings.StandaloneInventorySource); | ||
98 | |||
99 | //foreach (IInventoryDataPlugin plugin in plugins) | ||
100 | //{ | ||
101 | // // Using the OSP wrapper plugin for database plugins should be made configurable at some point | ||
102 | // m_InventoryService.AddPlugin(new OspInventoryWrapperPlugin(plugin, this)); | ||
103 | //} | ||
104 | |||
105 | m_Enabled = true; | ||
106 | m_log.Info("[INVENTORY CONNECTOR]: Local asset connector enabled"); | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | |||
111 | public void PostInitialise() | ||
112 | { | ||
113 | } | ||
114 | |||
115 | public void Close() | ||
116 | { | ||
117 | } | ||
118 | |||
119 | public void AddRegion(Scene scene) | ||
120 | { | ||
121 | if (!m_Enabled) | ||
122 | return; | ||
123 | |||
124 | scene.RegisterModuleInterface<IInventoryService>(this); | ||
125 | } | ||
126 | |||
127 | public void RemoveRegion(Scene scene) | ||
128 | { | ||
129 | } | ||
130 | |||
131 | public void RegionLoaded(Scene scene) | ||
132 | { | ||
133 | if (!m_Enabled) | ||
134 | return; | ||
135 | |||
136 | m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); | ||
137 | |||
138 | } | ||
139 | |||
140 | public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) | ||
141 | { | ||
142 | m_InventoryService.GetUserInventory(userID, callback); | ||
143 | } | ||
144 | |||
145 | /// <summary> | ||
146 | /// Add a new folder to the user's inventory | ||
147 | /// </summary> | ||
148 | /// <param name="folder"></param> | ||
149 | /// <returns>true if the folder was successfully added</returns> | ||
150 | public bool AddFolder(InventoryFolderBase folder) | ||
151 | { | ||
152 | return m_InventoryService.AddFolder(folder); | ||
153 | } | ||
154 | |||
155 | /// <summary> | ||
156 | /// Update a folder in the user's inventory | ||
157 | /// </summary> | ||
158 | /// <param name="folder"></param> | ||
159 | /// <returns>true if the folder was successfully updated</returns> | ||
160 | public bool UpdateFolder(InventoryFolderBase folder) | ||
161 | { | ||
162 | return m_InventoryService.UpdateFolder(folder); | ||
163 | } | ||
164 | |||
165 | /// <summary> | ||
166 | /// Move an inventory folder to a new location | ||
167 | /// </summary> | ||
168 | /// <param name="folder">A folder containing the details of the new location</param> | ||
169 | /// <returns>true if the folder was successfully moved</returns> | ||
170 | public bool MoveFolder(InventoryFolderBase folder) | ||
171 | { | ||
172 | return m_InventoryService.MoveFolder(folder); | ||
173 | } | ||
174 | |||
175 | /// <summary> | ||
176 | /// Purge an inventory folder of all its items and subfolders. | ||
177 | /// </summary> | ||
178 | /// <param name="folder"></param> | ||
179 | /// <returns>true if the folder was successfully purged</returns> | ||
180 | public bool PurgeFolder(InventoryFolderBase folder) | ||
181 | { | ||
182 | return m_InventoryService.PurgeFolder(folder); | ||
183 | } | ||
184 | |||
185 | /// <summary> | ||
186 | /// Add a new item to the user's inventory | ||
187 | /// </summary> | ||
188 | /// <param name="item"></param> | ||
189 | /// <returns>true if the item was successfully added</returns> | ||
190 | public bool AddItem(InventoryItemBase item) | ||
191 | { | ||
192 | return m_InventoryService.AddItem(item); | ||
193 | } | ||
194 | |||
195 | /// <summary> | ||
196 | /// Update an item in the user's inventory | ||
197 | /// </summary> | ||
198 | /// <param name="item"></param> | ||
199 | /// <returns>true if the item was successfully updated</returns> | ||
200 | public bool UpdateItem(InventoryItemBase item) | ||
201 | { | ||
202 | return m_InventoryService.UpdateItem(item); | ||
203 | } | ||
204 | |||
205 | /// <summary> | ||
206 | /// Delete an item from the user's inventory | ||
207 | /// </summary> | ||
208 | /// <param name="item"></param> | ||
209 | /// <returns>true if the item was successfully deleted</returns> | ||
210 | public bool DeleteItem(InventoryItemBase item) | ||
211 | { | ||
212 | return m_InventoryService.DeleteItem(item); | ||
213 | } | ||
214 | |||
215 | public InventoryItemBase QueryItem(InventoryItemBase item) | ||
216 | { | ||
217 | return m_InventoryService.QueryItem(item); | ||
218 | } | ||
219 | |||
220 | public InventoryFolderBase QueryFolder(InventoryFolderBase folder) | ||
221 | { | ||
222 | return m_InventoryService.QueryFolder(folder); | ||
223 | } | ||
224 | |||
225 | /// <summary> | ||
226 | /// Does the given user have an inventory structure? | ||
227 | /// </summary> | ||
228 | /// <param name="userID"></param> | ||
229 | /// <returns></returns> | ||
230 | public bool HasInventoryForUser(UUID userID) | ||
231 | { | ||
232 | return m_InventoryService.HasInventoryForUser(userID); | ||
233 | } | ||
234 | |||
235 | /// <summary> | ||
236 | /// Retrieve the root inventory folder for the given user. | ||
237 | /// </summary> | ||
238 | /// <param name="userID"></param> | ||
239 | /// <returns>null if no root folder was found</returns> | ||
240 | public InventoryFolderBase RequestRootFolder(UUID userID) | ||
241 | { | ||
242 | return m_InventoryService.RequestRootFolder(userID); | ||
243 | } | ||
244 | |||
245 | } | ||
246 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/RemoteInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/RemoteInventoryServiceConnector.cs new file mode 100644 index 0000000..ddb6cff --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/RemoteInventoryServiceConnector.cs | |||
@@ -0,0 +1,246 @@ | |||
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 | |||
28 | using log4net; | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using Nini.Config; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Statistics; | ||
35 | using OpenSim.Services.Connectors; | ||
36 | using OpenSim.Region.Framework.Interfaces; | ||
37 | using OpenSim.Region.Framework.Scenes; | ||
38 | using OpenSim.Services.Interfaces; | ||
39 | using OpenMetaverse; | ||
40 | |||
41 | namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory | ||
42 | { | ||
43 | public class RemoteInventoryServicesConnector : | ||
44 | ISharedRegionModule, IInventoryService | ||
45 | { | ||
46 | private static readonly ILog m_log = | ||
47 | LogManager.GetLogger( | ||
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private bool m_Enabled = false; | ||
51 | private bool m_Initialized = false; | ||
52 | private Scene m_Scene; | ||
53 | private InventoryServicesConnector m_RemoteConnector; | ||
54 | |||
55 | public string Name | ||
56 | { | ||
57 | get { return "RemoteInventoryServicesConnector"; } | ||
58 | } | ||
59 | |||
60 | public RemoteInventoryServicesConnector(IConfigSource source) | ||
61 | { | ||
62 | Init(source); | ||
63 | } | ||
64 | |||
65 | private void Init(IConfigSource source) | ||
66 | { | ||
67 | m_RemoteConnector = new InventoryServicesConnector(source); | ||
68 | } | ||
69 | |||
70 | |||
71 | #region ISharedRegionModule | ||
72 | |||
73 | public void Initialise(IConfigSource source) | ||
74 | { | ||
75 | IConfig moduleConfig = source.Configs["Modules"]; | ||
76 | if (moduleConfig != null) | ||
77 | { | ||
78 | string name = moduleConfig.GetString("InventoryServices", ""); | ||
79 | if (name == Name) | ||
80 | { | ||
81 | Init(source); | ||
82 | m_Enabled = true; | ||
83 | |||
84 | m_log.Info("[INVENTORY CONNECTOR]: Remote inventory enabled"); | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | |||
89 | public void PostInitialise() | ||
90 | { | ||
91 | } | ||
92 | |||
93 | public void Close() | ||
94 | { | ||
95 | } | ||
96 | |||
97 | public void AddRegion(Scene scene) | ||
98 | { | ||
99 | if (!m_Enabled) | ||
100 | return; | ||
101 | |||
102 | if (!m_Initialized) | ||
103 | m_Scene = scene; | ||
104 | |||
105 | scene.RegisterModuleInterface<IInventoryService>(this); | ||
106 | } | ||
107 | |||
108 | public void RemoveRegion(Scene scene) | ||
109 | { | ||
110 | } | ||
111 | |||
112 | public void RegionLoaded(Scene scene) | ||
113 | { | ||
114 | if (!m_Enabled) | ||
115 | return; | ||
116 | |||
117 | m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled remote inventory for region {0}", scene.RegionInfo.RegionName); | ||
118 | |||
119 | } | ||
120 | |||
121 | #endregion ISharedRegionModule | ||
122 | |||
123 | #region IInventoryService | ||
124 | |||
125 | public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) | ||
126 | { | ||
127 | UUID sessionID = GetSessionID(userID); | ||
128 | try | ||
129 | { | ||
130 | m_RemoteConnector.GetUserInventory(userID.ToString(), sessionID, callback); | ||
131 | } | ||
132 | catch (Exception e) | ||
133 | { | ||
134 | if (StatsManager.SimExtraStats != null) | ||
135 | StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); | ||
136 | |||
137 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Request inventory operation failed, {0} {1}", | ||
138 | e.Source, e.Message); | ||
139 | } | ||
140 | |||
141 | } | ||
142 | |||
143 | public bool AddFolder(InventoryFolderBase folder) | ||
144 | { | ||
145 | if (folder == null) | ||
146 | return false; | ||
147 | |||
148 | UUID sessionID = GetSessionID(folder.Owner); | ||
149 | return m_RemoteConnector.AddFolder(folder.Owner.ToString(), folder, sessionID); | ||
150 | } | ||
151 | |||
152 | public bool UpdateFolder(InventoryFolderBase folder) | ||
153 | { | ||
154 | if (folder == null) | ||
155 | return false; | ||
156 | |||
157 | UUID sessionID = GetSessionID(folder.Owner); | ||
158 | return m_RemoteConnector.UpdateFolder(folder.Owner.ToString(), folder, sessionID); | ||
159 | } | ||
160 | |||
161 | public bool MoveFolder(InventoryFolderBase folder) | ||
162 | { | ||
163 | if (folder == null) | ||
164 | return false; | ||
165 | |||
166 | UUID sessionID = GetSessionID(folder.Owner); | ||
167 | return m_RemoteConnector.MoveFolder(folder.Owner.ToString(), folder, sessionID); | ||
168 | } | ||
169 | |||
170 | public bool PurgeFolder(InventoryFolderBase folder) | ||
171 | { | ||
172 | if (folder == null) | ||
173 | return false; | ||
174 | |||
175 | UUID sessionID = GetSessionID(folder.Owner); | ||
176 | return m_RemoteConnector.PurgeFolder(folder.Owner.ToString(), folder, sessionID); | ||
177 | } | ||
178 | |||
179 | public bool AddItem(InventoryItemBase item) | ||
180 | { | ||
181 | if (item == null) | ||
182 | return false; | ||
183 | |||
184 | UUID sessionID = GetSessionID(item.Owner); | ||
185 | return m_RemoteConnector.AddItem(item.Owner.ToString(), item, sessionID); | ||
186 | } | ||
187 | |||
188 | public bool UpdateItem(InventoryItemBase item) | ||
189 | { | ||
190 | if (item == null) | ||
191 | return false; | ||
192 | |||
193 | UUID sessionID = GetSessionID(item.Owner); | ||
194 | return m_RemoteConnector.UpdateItem(item.Owner.ToString(), item, sessionID); | ||
195 | } | ||
196 | |||
197 | public bool DeleteItem(InventoryItemBase item) | ||
198 | { | ||
199 | if (item == null) | ||
200 | return false; | ||
201 | |||
202 | UUID sessionID = GetSessionID(item.Owner); | ||
203 | return m_RemoteConnector.DeleteItem(item.Owner.ToString(), item, sessionID); | ||
204 | } | ||
205 | |||
206 | public InventoryItemBase QueryItem(InventoryItemBase item) | ||
207 | { | ||
208 | if (item == null) | ||
209 | return null; | ||
210 | |||
211 | UUID sessionID = GetSessionID(item.Owner); | ||
212 | return m_RemoteConnector.QueryItem(item.Owner.ToString(), item, sessionID); | ||
213 | } | ||
214 | |||
215 | public InventoryFolderBase QueryFolder(InventoryFolderBase folder) | ||
216 | { | ||
217 | if (folder == null) | ||
218 | return null; | ||
219 | |||
220 | UUID sessionID = GetSessionID(folder.Owner); | ||
221 | return m_RemoteConnector.QueryFolder(folder.Owner.ToString(), folder, sessionID); | ||
222 | } | ||
223 | |||
224 | public bool HasInventoryForUser(UUID userID) | ||
225 | { | ||
226 | return false; | ||
227 | } | ||
228 | |||
229 | public InventoryFolderBase RequestRootFolder(UUID userID) | ||
230 | { | ||
231 | return null; | ||
232 | } | ||
233 | |||
234 | #endregion | ||
235 | |||
236 | private UUID GetSessionID(UUID userID) | ||
237 | { | ||
238 | ScenePresence sp = m_Scene.GetScenePresence(userID); | ||
239 | if (sp != null) | ||
240 | return sp.ControllingClient.SessionId; | ||
241 | |||
242 | return UUID.Zero; | ||
243 | } | ||
244 | |||
245 | } | ||
246 | } | ||
diff --git a/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs b/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs new file mode 100644 index 0000000..4fc4363 --- /dev/null +++ b/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs | |||
@@ -0,0 +1,107 @@ | |||
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 | |||
28 | using OpenSim.Framework; | ||
29 | using OpenSim.Services.Interfaces; | ||
30 | using OpenMetaverse; | ||
31 | |||
32 | namespace OpenSim.Services.Connectors | ||
33 | { | ||
34 | /// <summary> | ||
35 | /// Defines all operations to access a remote inventory service | ||
36 | /// using session authentication as a form of security. | ||
37 | /// </summary> | ||
38 | public interface ISessionAuthInventoryService | ||
39 | { | ||
40 | string Host | ||
41 | { | ||
42 | get; | ||
43 | } | ||
44 | |||
45 | /// <summary> | ||
46 | /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the | ||
47 | /// inventory has been received | ||
48 | /// </summary> | ||
49 | /// <param name="userID"></param> | ||
50 | /// <param name="callback"></param> | ||
51 | void GetUserInventory(string userID, UUID session_id, InventoryReceiptCallback callback); | ||
52 | |||
53 | /// <summary> | ||
54 | /// Add a new folder to the user's inventory | ||
55 | /// </summary> | ||
56 | /// <param name="folder"></param> | ||
57 | /// <returns>true if the folder was successfully added</returns> | ||
58 | bool AddFolder(string userID, InventoryFolderBase folder, UUID session_id); | ||
59 | |||
60 | /// <summary> | ||
61 | /// Update a folder in the user's inventory | ||
62 | /// </summary> | ||
63 | /// <param name="folder"></param> | ||
64 | /// <returns>true if the folder was successfully updated</returns> | ||
65 | bool UpdateFolder(string userID, InventoryFolderBase folder, UUID session_id); | ||
66 | |||
67 | /// <summary> | ||
68 | /// Move an inventory folder to a new location | ||
69 | /// </summary> | ||
70 | /// <param name="folder">A folder containing the details of the new location</param> | ||
71 | /// <returns>true if the folder was successfully moved</returns> | ||
72 | bool MoveFolder(string userID, InventoryFolderBase folder, UUID session_id); | ||
73 | |||
74 | /// <summary> | ||
75 | /// Purge an inventory folder of all its items and subfolders. | ||
76 | /// </summary> | ||
77 | /// <param name="folder"></param> | ||
78 | /// <returns>true if the folder was successfully purged</returns> | ||
79 | bool PurgeFolder(string userID, InventoryFolderBase folder, UUID session_id); | ||
80 | |||
81 | /// <summary> | ||
82 | /// Add a new item to the user's inventory | ||
83 | /// </summary> | ||
84 | /// <param name="item"></param> | ||
85 | /// <returns>true if the item was successfully added</returns> | ||
86 | bool AddItem(string userID, InventoryItemBase item, UUID session_id); | ||
87 | |||
88 | /// <summary> | ||
89 | /// Update an item in the user's inventory | ||
90 | /// </summary> | ||
91 | /// <param name="item"></param> | ||
92 | /// <returns>true if the item was successfully updated</returns> | ||
93 | bool UpdateItem(string userID, InventoryItemBase item, UUID session_id); | ||
94 | |||
95 | /// <summary> | ||
96 | /// Delete an item from the user's inventory | ||
97 | /// </summary> | ||
98 | /// <param name="item"></param> | ||
99 | /// <returns>true if the item was successfully deleted</returns> | ||
100 | bool DeleteItem(string userID, InventoryItemBase item, UUID session_id); | ||
101 | |||
102 | InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID session_id); | ||
103 | |||
104 | InventoryFolderBase QueryFolder(string userID, InventoryFolderBase item, UUID session_id); | ||
105 | |||
106 | } | ||
107 | } | ||
diff --git a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs new file mode 100644 index 0000000..34478ae --- /dev/null +++ b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs | |||
@@ -0,0 +1,343 @@ | |||
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 | |||
28 | using log4net; | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.IO; | ||
32 | using System.Reflection; | ||
33 | using Nini.Config; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Framework.Servers.HttpServer; | ||
36 | using OpenSim.Services.Interfaces; | ||
37 | using OpenMetaverse; | ||
38 | |||
39 | namespace OpenSim.Services.Connectors | ||
40 | { | ||
41 | public class InventoryServicesConnector : ISessionAuthInventoryService | ||
42 | { | ||
43 | private static readonly ILog m_log = | ||
44 | LogManager.GetLogger( | ||
45 | MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | |||
47 | private string m_ServerURI = String.Empty; | ||
48 | |||
49 | private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory = new Dictionary<UUID, InventoryReceiptCallback>(); | ||
50 | |||
51 | public InventoryServicesConnector() | ||
52 | { | ||
53 | } | ||
54 | |||
55 | public InventoryServicesConnector(string serverURI) | ||
56 | { | ||
57 | m_ServerURI = serverURI.TrimEnd('/'); | ||
58 | } | ||
59 | |||
60 | public InventoryServicesConnector(IConfigSource source) | ||
61 | { | ||
62 | Initialise(source); | ||
63 | } | ||
64 | |||
65 | public virtual void Initialise(IConfigSource source) | ||
66 | { | ||
67 | IConfig inventoryConfig = source.Configs["InventoryService"]; | ||
68 | if (inventoryConfig == null) | ||
69 | { | ||
70 | m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpanSim.ini"); | ||
71 | throw new Exception("Inventory connector init error"); | ||
72 | } | ||
73 | |||
74 | string serviceURI = inventoryConfig.GetString("InventoryServerURI", | ||
75 | String.Empty); | ||
76 | |||
77 | if (serviceURI == String.Empty) | ||
78 | { | ||
79 | m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); | ||
80 | throw new Exception("Inventory connector init error"); | ||
81 | } | ||
82 | m_ServerURI = serviceURI.TrimEnd('/'); | ||
83 | } | ||
84 | |||
85 | #region ISessionAuthInventoryService | ||
86 | |||
87 | public string Host | ||
88 | { | ||
89 | get { return m_ServerURI; } | ||
90 | } | ||
91 | |||
92 | /// <summary> | ||
93 | /// Caller must catch eventual Exceptions. | ||
94 | /// </summary> | ||
95 | /// <param name="userID"></param> | ||
96 | /// <param name="sessionID"></param> | ||
97 | /// <param name="callback"></param> | ||
98 | public void GetUserInventory(string userIDStr, UUID sessionID, InventoryReceiptCallback callback) | ||
99 | { | ||
100 | UUID userID = UUID.Zero; | ||
101 | if (UUID.TryParse(userIDStr, out userID)) | ||
102 | { | ||
103 | lock (m_RequestingInventory) | ||
104 | { | ||
105 | if (!m_RequestingInventory.ContainsKey(userID)) | ||
106 | m_RequestingInventory.Add(userID, callback); | ||
107 | else | ||
108 | { | ||
109 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetUserInventory - ignoring repeated request for user {0}", userID); | ||
110 | return; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | m_log.InfoFormat( | ||
115 | "[INVENTORY CONNECTOR]: Requesting inventory from {0}/GetInventory/ for user {1}", | ||
116 | m_ServerURI, userID); | ||
117 | |||
118 | RestSessionObjectPosterResponse<Guid, InventoryCollection> requester | ||
119 | = new RestSessionObjectPosterResponse<Guid, InventoryCollection>(); | ||
120 | requester.ResponseCallback = InventoryResponse; | ||
121 | |||
122 | requester.BeginPostObject(m_ServerURI + "/GetInventory/", userID.Guid, sessionID.ToString(), userID.ToString()); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | public bool AddFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
127 | { | ||
128 | try | ||
129 | { | ||
130 | return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject( | ||
131 | "POST", m_ServerURI + "/NewFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); | ||
132 | } | ||
133 | catch (Exception e) | ||
134 | { | ||
135 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory folder operation failed, {0} {1}", | ||
136 | e.Source, e.Message); | ||
137 | } | ||
138 | |||
139 | return false; | ||
140 | } | ||
141 | |||
142 | public bool UpdateFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
143 | { | ||
144 | try | ||
145 | { | ||
146 | return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject( | ||
147 | "POST", m_ServerURI + "/UpdateFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); | ||
148 | } | ||
149 | catch (Exception e) | ||
150 | { | ||
151 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update inventory folder operation failed, {0} {1}", | ||
152 | e.Source, e.Message); | ||
153 | } | ||
154 | |||
155 | return false; | ||
156 | } | ||
157 | |||
158 | public bool MoveFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
159 | { | ||
160 | try | ||
161 | { | ||
162 | return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject( | ||
163 | "POST", m_ServerURI + "/MoveFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); | ||
164 | } | ||
165 | catch (Exception e) | ||
166 | { | ||
167 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory folder operation failed, {0} {1}", | ||
168 | e.Source, e.Message); | ||
169 | } | ||
170 | |||
171 | return false; | ||
172 | } | ||
173 | |||
174 | public bool PurgeFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
175 | { | ||
176 | try | ||
177 | { | ||
178 | return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject( | ||
179 | "POST", m_ServerURI + "/PurgeFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); | ||
180 | } | ||
181 | catch (Exception e) | ||
182 | { | ||
183 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory folder operation failed, {0} {1}", | ||
184 | e.Source, e.Message); | ||
185 | } | ||
186 | |||
187 | return false; | ||
188 | } | ||
189 | |||
190 | public bool AddItem(string userID, InventoryItemBase item, UUID sessionID) | ||
191 | { | ||
192 | try | ||
193 | { | ||
194 | return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject( | ||
195 | "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString()); | ||
196 | } | ||
197 | catch (Exception e) | ||
198 | { | ||
199 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory item operation failed, {0} {1}", | ||
200 | e.Source, e.Message); | ||
201 | } | ||
202 | |||
203 | return false; | ||
204 | } | ||
205 | |||
206 | public bool UpdateItem(string userID, InventoryItemBase item, UUID sessionID) | ||
207 | { | ||
208 | try | ||
209 | { | ||
210 | return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject( | ||
211 | "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString()); | ||
212 | } | ||
213 | catch (Exception e) | ||
214 | { | ||
215 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update new inventory item operation failed, {0} {1}", | ||
216 | e.Source, e.Message); | ||
217 | } | ||
218 | |||
219 | return false; | ||
220 | } | ||
221 | |||
222 | public bool DeleteItem(string userID, InventoryItemBase item, UUID sessionID) | ||
223 | { | ||
224 | try | ||
225 | { | ||
226 | return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject( | ||
227 | "POST", m_ServerURI + "/DeleteItem/", item, sessionID.ToString(), item.Owner.ToString()); | ||
228 | } | ||
229 | catch (Exception e) | ||
230 | { | ||
231 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory item operation failed, {0} {1}", | ||
232 | e.Source, e.Message); | ||
233 | } | ||
234 | |||
235 | return false; | ||
236 | } | ||
237 | |||
238 | public InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID sessionID) | ||
239 | { | ||
240 | try | ||
241 | { | ||
242 | return SynchronousRestSessionObjectPoster<InventoryItemBase, InventoryItemBase>.BeginPostObject( | ||
243 | "POST", m_ServerURI + "/QueryItem/", item, sessionID.ToString(), item.Owner.ToString()); | ||
244 | } | ||
245 | catch (Exception e) | ||
246 | { | ||
247 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory item operation failed, {0} {1}", | ||
248 | e.Source, e.Message); | ||
249 | } | ||
250 | |||
251 | return null; | ||
252 | } | ||
253 | |||
254 | public InventoryFolderBase QueryFolder(string userID, InventoryFolderBase item, UUID sessionID) | ||
255 | { | ||
256 | try | ||
257 | { | ||
258 | return SynchronousRestSessionObjectPoster<InventoryFolderBase, InventoryFolderBase>.BeginPostObject( | ||
259 | "POST", m_ServerURI + "/QueryFolder/", item, sessionID.ToString(), item.Owner.ToString()); | ||
260 | } | ||
261 | catch (Exception e) | ||
262 | { | ||
263 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory item operation failed, {0} {1}", | ||
264 | e.Source, e.Message); | ||
265 | } | ||
266 | |||
267 | return null; | ||
268 | } | ||
269 | |||
270 | #endregion | ||
271 | |||
272 | /// <summary> | ||
273 | /// Callback used by the inventory server GetInventory request | ||
274 | /// </summary> | ||
275 | /// <param name="userID"></param> | ||
276 | private void InventoryResponse(InventoryCollection response) | ||
277 | { | ||
278 | UUID userID = response.UserID; | ||
279 | InventoryReceiptCallback callback = null; | ||
280 | lock (m_RequestingInventory) | ||
281 | { | ||
282 | if (m_RequestingInventory.ContainsKey(userID)) | ||
283 | { | ||
284 | callback = m_RequestingInventory[userID]; | ||
285 | m_RequestingInventory.Remove(userID); | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | m_log.WarnFormat( | ||
290 | "[INVENTORY CONNECTOR]: " + | ||
291 | "Received inventory response for {0} for which we do not have a record of requesting!", | ||
292 | userID); | ||
293 | return; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | m_log.InfoFormat("[INVENTORY CONNECTOR]: " + | ||
298 | "Received inventory response for user {0} containing {1} folders and {2} items", | ||
299 | userID, response.Folders.Count, response.Items.Count); | ||
300 | |||
301 | InventoryFolderImpl rootFolder = null; | ||
302 | |||
303 | ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>(); | ||
304 | ICollection<InventoryItemBase> items = new List<InventoryItemBase>(); | ||
305 | |||
306 | foreach (InventoryFolderBase folder in response.Folders) | ||
307 | { | ||
308 | if (folder.ParentID == UUID.Zero) | ||
309 | { | ||
310 | rootFolder = new InventoryFolderImpl(folder); | ||
311 | folders.Add(rootFolder); | ||
312 | |||
313 | break; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | if (rootFolder != null) | ||
318 | { | ||
319 | foreach (InventoryFolderBase folder in response.Folders) | ||
320 | { | ||
321 | if (folder.ID != rootFolder.ID) | ||
322 | { | ||
323 | folders.Add(new InventoryFolderImpl(folder)); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | foreach (InventoryItemBase item in response.Items) | ||
328 | { | ||
329 | items.Add(item); | ||
330 | } | ||
331 | } | ||
332 | else | ||
333 | { | ||
334 | m_log.ErrorFormat("[INVENTORY CONNECTOR]: Did not get back an inventory containing a root folder for user {0}", userID); | ||
335 | } | ||
336 | |||
337 | callback(folders, items); | ||
338 | |||
339 | } | ||
340 | |||
341 | |||
342 | } | ||
343 | } | ||
diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs new file mode 100644 index 0000000..9fe419f --- /dev/null +++ b/OpenSim/Services/Interfaces/IInventoryService.cs | |||
@@ -0,0 +1,118 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenSim.Framework; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Services.Interfaces | ||
34 | { | ||
35 | /// <summary> | ||
36 | /// Callback used when a user's inventory is received from the inventory service | ||
37 | /// </summary> | ||
38 | public delegate void InventoryReceiptCallback( | ||
39 | ICollection<InventoryFolderImpl> folders, ICollection<InventoryItemBase> items); | ||
40 | |||
41 | public interface IInventoryService | ||
42 | { | ||
43 | /// <summary> | ||
44 | /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the | ||
45 | /// inventory has been received | ||
46 | /// </summary> | ||
47 | /// <param name="userID"></param> | ||
48 | /// <param name="callback"></param> | ||
49 | void GetUserInventory(UUID userID, InventoryReceiptCallback callback); | ||
50 | |||
51 | /// <summary> | ||
52 | /// Add a new folder to the user's inventory | ||
53 | /// </summary> | ||
54 | /// <param name="folder"></param> | ||
55 | /// <returns>true if the folder was successfully added</returns> | ||
56 | bool AddFolder(InventoryFolderBase folder); | ||
57 | |||
58 | /// <summary> | ||
59 | /// Update a folder in the user's inventory | ||
60 | /// </summary> | ||
61 | /// <param name="folder"></param> | ||
62 | /// <returns>true if the folder was successfully updated</returns> | ||
63 | bool UpdateFolder(InventoryFolderBase folder); | ||
64 | |||
65 | /// <summary> | ||
66 | /// Move an inventory folder to a new location | ||
67 | /// </summary> | ||
68 | /// <param name="folder">A folder containing the details of the new location</param> | ||
69 | /// <returns>true if the folder was successfully moved</returns> | ||
70 | bool MoveFolder(InventoryFolderBase folder); | ||
71 | |||
72 | /// <summary> | ||
73 | /// Purge an inventory folder of all its items and subfolders. | ||
74 | /// </summary> | ||
75 | /// <param name="folder"></param> | ||
76 | /// <returns>true if the folder was successfully purged</returns> | ||
77 | bool PurgeFolder(InventoryFolderBase folder); | ||
78 | |||
79 | /// <summary> | ||
80 | /// Add a new item to the user's inventory | ||
81 | /// </summary> | ||
82 | /// <param name="item"></param> | ||
83 | /// <returns>true if the item was successfully added</returns> | ||
84 | bool AddItem(InventoryItemBase item); | ||
85 | |||
86 | /// <summary> | ||
87 | /// Update an item in the user's inventory | ||
88 | /// </summary> | ||
89 | /// <param name="item"></param> | ||
90 | /// <returns>true if the item was successfully updated</returns> | ||
91 | bool UpdateItem(InventoryItemBase item); | ||
92 | |||
93 | /// <summary> | ||
94 | /// Delete an item from the user's inventory | ||
95 | /// </summary> | ||
96 | /// <param name="item"></param> | ||
97 | /// <returns>true if the item was successfully deleted</returns> | ||
98 | bool DeleteItem(InventoryItemBase item); | ||
99 | |||
100 | InventoryItemBase QueryItem(InventoryItemBase item); | ||
101 | |||
102 | InventoryFolderBase QueryFolder(InventoryFolderBase folder); | ||
103 | |||
104 | /// <summary> | ||
105 | /// Does the given user have an inventory structure? | ||
106 | /// </summary> | ||
107 | /// <param name="userID"></param> | ||
108 | /// <returns></returns> | ||
109 | bool HasInventoryForUser(UUID userID); | ||
110 | |||
111 | /// <summary> | ||
112 | /// Retrieve the root inventory folder for the given user. | ||
113 | /// </summary> | ||
114 | /// <param name="userID"></param> | ||
115 | /// <returns>null if no root folder was found</returns> | ||
116 | InventoryFolderBase RequestRootFolder(UUID userID); | ||
117 | } | ||
118 | } | ||
diff --git a/OpenSim/Services/InventoryService/HGInventoryService.cs b/OpenSim/Services/InventoryService/HGInventoryService.cs new file mode 100644 index 0000000..e5e40c6 --- /dev/null +++ b/OpenSim/Services/InventoryService/HGInventoryService.cs | |||
@@ -0,0 +1,178 @@ | |||
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 | |||
28 | using log4net; | ||
29 | using Nini.Config; | ||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Reflection; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Services.Interfaces; | ||
35 | using OpenSim.Services.Connectors; | ||
36 | using OpenMetaverse; | ||
37 | |||
38 | namespace OpenSim.Services.InventoryService | ||
39 | { | ||
40 | public class HGInventoryService : ISessionAuthInventoryService | ||
41 | { | ||
42 | private static readonly ILog m_log = | ||
43 | LogManager.GetLogger( | ||
44 | MethodBase.GetCurrentMethod().DeclaringType); | ||
45 | |||
46 | private Dictionary<string, InventoryServicesConnector> m_connectors = new Dictionary<string, InventoryServicesConnector>(); | ||
47 | |||
48 | public HGInventoryService(IConfigSource source) | ||
49 | { | ||
50 | IConfig moduleConfig = source.Configs["Modules"]; | ||
51 | if (moduleConfig != null) | ||
52 | { | ||
53 | |||
54 | IConfig assetConfig = source.Configs["InventoryService"]; | ||
55 | if (assetConfig == null) | ||
56 | { | ||
57 | m_log.Error("[HG INVENTORY SERVICE]: InventoryService missing from OpenSim.ini"); | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | m_log.Info("[HG INVENTORY SERVICE]: HG inventory service enabled"); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | private bool StringToUrlAndUserID(string id, out string url, out string userID) | ||
66 | { | ||
67 | url = String.Empty; | ||
68 | userID = String.Empty; | ||
69 | |||
70 | Uri assetUri; | ||
71 | |||
72 | if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) && | ||
73 | assetUri.Scheme == Uri.UriSchemeHttp) | ||
74 | { | ||
75 | url = "http://" + assetUri.Authority; | ||
76 | userID = assetUri.LocalPath.Trim(new char[] { '/' }); | ||
77 | return true; | ||
78 | } | ||
79 | |||
80 | return false; | ||
81 | } | ||
82 | private ISessionAuthInventoryService GetConnector(string url) | ||
83 | { | ||
84 | InventoryServicesConnector connector = null; | ||
85 | lock (m_connectors) | ||
86 | { | ||
87 | if (m_connectors.ContainsKey(url)) | ||
88 | { | ||
89 | connector = m_connectors[url]; | ||
90 | } | ||
91 | else | ||
92 | { | ||
93 | // We're instantiating this class explicitly, but this won't | ||
94 | // work in general, because the remote grid may be running | ||
95 | // an inventory server that has a different protocol. | ||
96 | // Eventually we will want a piece of protocol asking | ||
97 | // the remote server about its kind. Definitely cool thing to do! | ||
98 | connector = new InventoryServicesConnector(url); | ||
99 | m_connectors.Add(url, connector); | ||
100 | } | ||
101 | } | ||
102 | return connector; | ||
103 | } | ||
104 | |||
105 | public string Host | ||
106 | { | ||
107 | get { return string.Empty; } | ||
108 | } | ||
109 | |||
110 | public void GetUserInventory(string id, UUID sessionID, InventoryReceiptCallback callback) | ||
111 | { | ||
112 | string url = string.Empty; | ||
113 | string userID = string.Empty; | ||
114 | |||
115 | if (StringToUrlAndUserID(id, out url, out userID)) | ||
116 | { | ||
117 | ISessionAuthInventoryService connector = GetConnector(url); | ||
118 | connector.GetUserInventory(userID, sessionID, callback); | ||
119 | } | ||
120 | |||
121 | } | ||
122 | |||
123 | public bool AddFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
124 | { | ||
125 | // TODO | ||
126 | return false; | ||
127 | } | ||
128 | |||
129 | public bool UpdateFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
130 | { | ||
131 | // TODO | ||
132 | return false; | ||
133 | } | ||
134 | |||
135 | public bool MoveFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
136 | { | ||
137 | // TODO | ||
138 | return false; | ||
139 | } | ||
140 | |||
141 | public bool PurgeFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
142 | { | ||
143 | // TODO | ||
144 | return false; | ||
145 | } | ||
146 | |||
147 | public bool AddItem(string userID, InventoryItemBase item, UUID sessionID) | ||
148 | { | ||
149 | // TODO | ||
150 | return false; | ||
151 | } | ||
152 | |||
153 | public bool UpdateItem(string userID, InventoryItemBase item, UUID sessionID) | ||
154 | { | ||
155 | // TODO | ||
156 | return false; | ||
157 | } | ||
158 | |||
159 | public bool DeleteItem(string userID, InventoryItemBase item, UUID sessionID) | ||
160 | { | ||
161 | // TODO | ||
162 | return false; | ||
163 | } | ||
164 | |||
165 | public InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID sessionID) | ||
166 | { | ||
167 | // TODO | ||
168 | return null; | ||
169 | } | ||
170 | |||
171 | public InventoryFolderBase QueryFolder(string userID, InventoryFolderBase folder, UUID sessionID) | ||
172 | { | ||
173 | // TODO | ||
174 | return null; | ||
175 | } | ||
176 | |||
177 | } | ||
178 | } | ||
diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs new file mode 100644 index 0000000..b4e2549 --- /dev/null +++ b/OpenSim/Services/InventoryService/InventoryService.cs | |||
@@ -0,0 +1,544 @@ | |||
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 | |||
28 | using System.Collections.Generic; | ||
29 | using System.Reflection; | ||
30 | using log4net; | ||
31 | using Nini.Config; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Data; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Services.Interfaces; | ||
36 | |||
37 | namespace OpenSim.Services.InventoryService | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// The Inventory service reference implementation | ||
41 | /// </summary> | ||
42 | public class InventoryService : InventoryServiceBase, IInventoryService | ||
43 | { | ||
44 | private static readonly ILog m_log | ||
45 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | |||
47 | public InventoryService(IConfigSource config) : base(config) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | #region IInventoryServices methods | ||
52 | |||
53 | public string Host | ||
54 | { | ||
55 | get { return "default"; } | ||
56 | } | ||
57 | |||
58 | public List<InventoryFolderBase> GetInventorySkeleton(UUID userId) | ||
59 | { | ||
60 | // m_log.DebugFormat("[AGENT INVENTORY]: Getting inventory skeleton for {0}", userId); | ||
61 | |||
62 | InventoryFolderBase rootFolder = RequestRootFolder(userId); | ||
63 | |||
64 | // Agent has no inventory structure yet. | ||
65 | if (null == rootFolder) | ||
66 | { | ||
67 | return null; | ||
68 | } | ||
69 | |||
70 | List<InventoryFolderBase> userFolders = new List<InventoryFolderBase>(); | ||
71 | |||
72 | userFolders.Add(rootFolder); | ||
73 | |||
74 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
75 | { | ||
76 | IList<InventoryFolderBase> folders = plugin.getFolderHierarchy(rootFolder.ID); | ||
77 | userFolders.AddRange(folders); | ||
78 | } | ||
79 | |||
80 | // foreach (InventoryFolderBase folder in userFolders) | ||
81 | // { | ||
82 | // m_log.DebugFormat("[AGENT INVENTORY]: Got folder {0} {1}", folder.name, folder.folderID); | ||
83 | // } | ||
84 | |||
85 | return userFolders; | ||
86 | } | ||
87 | |||
88 | // See IInventoryServices | ||
89 | public virtual bool HasInventoryForUser(UUID userID) | ||
90 | { | ||
91 | return false; | ||
92 | } | ||
93 | |||
94 | // See IInventoryServices | ||
95 | public virtual InventoryFolderBase RequestRootFolder(UUID userID) | ||
96 | { | ||
97 | // Retrieve the first root folder we get from the list of plugins. | ||
98 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
99 | { | ||
100 | InventoryFolderBase rootFolder = plugin.getUserRootFolder(userID); | ||
101 | if (rootFolder != null) | ||
102 | return rootFolder; | ||
103 | } | ||
104 | |||
105 | // Return nothing if no plugin was able to supply a root folder | ||
106 | return null; | ||
107 | } | ||
108 | |||
109 | // See IInventoryServices | ||
110 | public bool CreateNewUserInventory(UUID user) | ||
111 | { | ||
112 | InventoryFolderBase existingRootFolder = RequestRootFolder(user); | ||
113 | |||
114 | if (null != existingRootFolder) | ||
115 | { | ||
116 | m_log.WarnFormat( | ||
117 | "[AGENT INVENTORY]: Did not create a new inventory for user {0} since they already have " | ||
118 | + "a root inventory folder with id {1}", | ||
119 | user, existingRootFolder.ID); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | UsersInventory inven = new UsersInventory(); | ||
124 | inven.CreateNewInventorySet(user); | ||
125 | AddNewInventorySet(inven); | ||
126 | |||
127 | return true; | ||
128 | } | ||
129 | |||
130 | return false; | ||
131 | } | ||
132 | |||
133 | // See IInventoryServices | ||
134 | public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) | ||
135 | { | ||
136 | m_log.InfoFormat("[LOCAL INVENTORY SERVICE]: Requesting inventory for user {0}", userID); | ||
137 | |||
138 | List<InventoryFolderImpl> folders = new List<InventoryFolderImpl>(); | ||
139 | List<InventoryItemBase> items = new List<InventoryItemBase>(); | ||
140 | |||
141 | List<InventoryFolderBase> skeletonFolders = GetInventorySkeleton(userID); | ||
142 | |||
143 | if (skeletonFolders != null) | ||
144 | { | ||
145 | |||
146 | InventoryFolderImpl rootFolder = null; | ||
147 | |||
148 | // Need to retrieve the root folder on the first pass | ||
149 | foreach (InventoryFolderBase folder in skeletonFolders) | ||
150 | { | ||
151 | if (folder.ParentID == UUID.Zero) | ||
152 | { | ||
153 | rootFolder = new InventoryFolderImpl(folder); | ||
154 | folders.Add(rootFolder); | ||
155 | items.AddRange(RequestFolderItems(rootFolder.ID)); | ||
156 | break; // Only 1 root folder per user | ||
157 | } | ||
158 | } | ||
159 | |||
160 | if (rootFolder != null) | ||
161 | { | ||
162 | foreach (InventoryFolderBase folder in skeletonFolders) | ||
163 | { | ||
164 | if (folder.ID != rootFolder.ID) | ||
165 | { | ||
166 | folders.Add(new InventoryFolderImpl(folder)); | ||
167 | items.AddRange(RequestFolderItems(folder.ID)); | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | m_log.InfoFormat( | ||
173 | "[LOCAL INVENTORY SERVICE]: Received inventory response for user {0} containing {1} folders and {2} items", | ||
174 | userID, folders.Count, items.Count); | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | m_log.WarnFormat("[LOCAL INVENTORY SERVICE]: User {0} inventory not available", userID); | ||
179 | } | ||
180 | |||
181 | callback(folders, items); | ||
182 | } | ||
183 | |||
184 | public List<InventoryItemBase> GetActiveGestures(UUID userId) | ||
185 | { | ||
186 | List<InventoryItemBase> activeGestures = new List<InventoryItemBase>(); | ||
187 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
188 | { | ||
189 | activeGestures.AddRange(plugin.fetchActiveGestures(userId)); | ||
190 | } | ||
191 | |||
192 | return activeGestures; | ||
193 | } | ||
194 | |||
195 | #endregion | ||
196 | |||
197 | #region Methods used by GridInventoryService | ||
198 | |||
199 | public List<InventoryFolderBase> RequestSubFolders(UUID parentFolderID) | ||
200 | { | ||
201 | List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>(); | ||
202 | |||
203 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
204 | { | ||
205 | inventoryList.AddRange(plugin.getInventoryFolders(parentFolderID)); | ||
206 | } | ||
207 | |||
208 | return inventoryList; | ||
209 | } | ||
210 | |||
211 | public List<InventoryItemBase> RequestFolderItems(UUID folderID) | ||
212 | { | ||
213 | List<InventoryItemBase> itemsList = new List<InventoryItemBase>(); | ||
214 | |||
215 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
216 | { | ||
217 | itemsList.AddRange(plugin.getInventoryInFolder(folderID)); | ||
218 | } | ||
219 | |||
220 | return itemsList; | ||
221 | } | ||
222 | |||
223 | #endregion | ||
224 | |||
225 | // See IInventoryServices | ||
226 | public virtual bool AddFolder(InventoryFolderBase folder) | ||
227 | { | ||
228 | m_log.DebugFormat( | ||
229 | "[AGENT INVENTORY]: Adding folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); | ||
230 | |||
231 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
232 | { | ||
233 | plugin.addInventoryFolder(folder); | ||
234 | } | ||
235 | |||
236 | // FIXME: Should return false on failure | ||
237 | return true; | ||
238 | } | ||
239 | |||
240 | // See IInventoryServices | ||
241 | public virtual bool UpdateFolder(InventoryFolderBase folder) | ||
242 | { | ||
243 | m_log.DebugFormat( | ||
244 | "[AGENT INVENTORY]: Updating folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); | ||
245 | |||
246 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
247 | { | ||
248 | plugin.updateInventoryFolder(folder); | ||
249 | } | ||
250 | |||
251 | // FIXME: Should return false on failure | ||
252 | return true; | ||
253 | } | ||
254 | |||
255 | // See IInventoryServices | ||
256 | public virtual bool MoveFolder(InventoryFolderBase folder) | ||
257 | { | ||
258 | m_log.DebugFormat( | ||
259 | "[AGENT INVENTORY]: Moving folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); | ||
260 | |||
261 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
262 | { | ||
263 | plugin.moveInventoryFolder(folder); | ||
264 | } | ||
265 | |||
266 | // FIXME: Should return false on failure | ||
267 | return true; | ||
268 | } | ||
269 | |||
270 | // See IInventoryServices | ||
271 | public virtual bool AddItem(InventoryItemBase item) | ||
272 | { | ||
273 | m_log.DebugFormat( | ||
274 | "[AGENT INVENTORY]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder); | ||
275 | |||
276 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
277 | { | ||
278 | plugin.addInventoryItem(item); | ||
279 | } | ||
280 | |||
281 | // FIXME: Should return false on failure | ||
282 | return true; | ||
283 | } | ||
284 | |||
285 | // See IInventoryServices | ||
286 | public virtual bool UpdateItem(InventoryItemBase item) | ||
287 | { | ||
288 | m_log.InfoFormat( | ||
289 | "[AGENT INVENTORY]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder); | ||
290 | |||
291 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
292 | { | ||
293 | plugin.updateInventoryItem(item); | ||
294 | } | ||
295 | |||
296 | // FIXME: Should return false on failure | ||
297 | return true; | ||
298 | } | ||
299 | |||
300 | // See IInventoryServices | ||
301 | public virtual bool DeleteItem(InventoryItemBase item) | ||
302 | { | ||
303 | m_log.InfoFormat( | ||
304 | "[AGENT INVENTORY]: Deleting item {0} {1} from folder {2}", item.Name, item.ID, item.Folder); | ||
305 | |||
306 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
307 | { | ||
308 | plugin.deleteInventoryItem(item.ID); | ||
309 | } | ||
310 | |||
311 | // FIXME: Should return false on failure | ||
312 | return true; | ||
313 | } | ||
314 | |||
315 | public virtual InventoryItemBase QueryItem(InventoryItemBase item) | ||
316 | { | ||
317 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
318 | { | ||
319 | InventoryItemBase result = plugin.queryInventoryItem(item.ID); | ||
320 | if (result != null) | ||
321 | return result; | ||
322 | } | ||
323 | |||
324 | return null; | ||
325 | } | ||
326 | |||
327 | public virtual InventoryFolderBase QueryFolder(InventoryFolderBase item) | ||
328 | { | ||
329 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
330 | { | ||
331 | InventoryFolderBase result = plugin.queryInventoryFolder(item.ID); | ||
332 | if (result != null) | ||
333 | return result; | ||
334 | } | ||
335 | |||
336 | return null; | ||
337 | } | ||
338 | |||
339 | /// <summary> | ||
340 | /// Purge a folder of all items items and subfolders. | ||
341 | /// | ||
342 | /// FIXME: Really nasty in a sense, because we have to query the database to get information we may | ||
343 | /// already know... Needs heavy refactoring. | ||
344 | /// </summary> | ||
345 | /// <param name="folder"></param> | ||
346 | public virtual bool PurgeFolder(InventoryFolderBase folder) | ||
347 | { | ||
348 | m_log.DebugFormat( | ||
349 | "[AGENT INVENTORY]: Purging folder {0} {1} of its contents", folder.Name, folder.ID); | ||
350 | |||
351 | List<InventoryFolderBase> subFolders = RequestSubFolders(folder.ID); | ||
352 | |||
353 | foreach (InventoryFolderBase subFolder in subFolders) | ||
354 | { | ||
355 | // m_log.DebugFormat("[AGENT INVENTORY]: Deleting folder {0} {1}", subFolder.Name, subFolder.ID); | ||
356 | |||
357 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
358 | { | ||
359 | plugin.deleteInventoryFolder(subFolder.ID); | ||
360 | } | ||
361 | } | ||
362 | |||
363 | List<InventoryItemBase> items = RequestFolderItems(folder.ID); | ||
364 | |||
365 | foreach (InventoryItemBase item in items) | ||
366 | { | ||
367 | DeleteItem(item); | ||
368 | } | ||
369 | |||
370 | // FIXME: Should return false on failure | ||
371 | return true; | ||
372 | } | ||
373 | |||
374 | private void AddNewInventorySet(UsersInventory inventory) | ||
375 | { | ||
376 | foreach (InventoryFolderBase folder in inventory.Folders.Values) | ||
377 | { | ||
378 | AddFolder(folder); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | public InventoryItemBase GetInventoryItem(UUID itemID) | ||
383 | { | ||
384 | foreach (IInventoryDataPlugin plugin in m_plugins) | ||
385 | { | ||
386 | InventoryItemBase item = plugin.getInventoryItem(itemID); | ||
387 | if (item != null) | ||
388 | return item; | ||
389 | } | ||
390 | |||
391 | return null; | ||
392 | } | ||
393 | |||
394 | /// <summary> | ||
395 | /// Used to create a new user inventory. | ||
396 | /// </summary> | ||
397 | private class UsersInventory | ||
398 | { | ||
399 | public Dictionary<UUID, InventoryFolderBase> Folders = new Dictionary<UUID, InventoryFolderBase>(); | ||
400 | public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>(); | ||
401 | |||
402 | public virtual void CreateNewInventorySet(UUID user) | ||
403 | { | ||
404 | InventoryFolderBase folder = new InventoryFolderBase(); | ||
405 | |||
406 | folder.ParentID = UUID.Zero; | ||
407 | folder.Owner = user; | ||
408 | folder.ID = UUID.Random(); | ||
409 | folder.Name = "My Inventory"; | ||
410 | folder.Type = (short)AssetType.Folder; | ||
411 | folder.Version = 1; | ||
412 | Folders.Add(folder.ID, folder); | ||
413 | |||
414 | UUID rootFolder = folder.ID; | ||
415 | |||
416 | folder = new InventoryFolderBase(); | ||
417 | folder.ParentID = rootFolder; | ||
418 | folder.Owner = user; | ||
419 | folder.ID = UUID.Random(); | ||
420 | folder.Name = "Animations"; | ||
421 | folder.Type = (short)AssetType.Animation; | ||
422 | folder.Version = 1; | ||
423 | Folders.Add(folder.ID, folder); | ||
424 | |||
425 | folder = new InventoryFolderBase(); | ||
426 | folder.ParentID = rootFolder; | ||
427 | folder.Owner = user; | ||
428 | folder.ID = UUID.Random(); | ||
429 | folder.Name = "Body Parts"; | ||
430 | folder.Type = (short)AssetType.Bodypart; | ||
431 | folder.Version = 1; | ||
432 | Folders.Add(folder.ID, folder); | ||
433 | |||
434 | folder = new InventoryFolderBase(); | ||
435 | folder.ParentID = rootFolder; | ||
436 | folder.Owner = user; | ||
437 | folder.ID = UUID.Random(); | ||
438 | folder.Name = "Calling Cards"; | ||
439 | folder.Type = (short)AssetType.CallingCard; | ||
440 | folder.Version = 1; | ||
441 | Folders.Add(folder.ID, folder); | ||
442 | |||
443 | folder = new InventoryFolderBase(); | ||
444 | folder.ParentID = rootFolder; | ||
445 | folder.Owner = user; | ||
446 | folder.ID = UUID.Random(); | ||
447 | folder.Name = "Clothing"; | ||
448 | folder.Type = (short)AssetType.Clothing; | ||
449 | folder.Version = 1; | ||
450 | Folders.Add(folder.ID, folder); | ||
451 | |||
452 | folder = new InventoryFolderBase(); | ||
453 | folder.ParentID = rootFolder; | ||
454 | folder.Owner = user; | ||
455 | folder.ID = UUID.Random(); | ||
456 | folder.Name = "Gestures"; | ||
457 | folder.Type = (short)AssetType.Gesture; | ||
458 | folder.Version = 1; | ||
459 | Folders.Add(folder.ID, folder); | ||
460 | |||
461 | folder = new InventoryFolderBase(); | ||
462 | folder.ParentID = rootFolder; | ||
463 | folder.Owner = user; | ||
464 | folder.ID = UUID.Random(); | ||
465 | folder.Name = "Landmarks"; | ||
466 | folder.Type = (short)AssetType.Landmark; | ||
467 | folder.Version = 1; | ||
468 | Folders.Add(folder.ID, folder); | ||
469 | |||
470 | folder = new InventoryFolderBase(); | ||
471 | folder.ParentID = rootFolder; | ||
472 | folder.Owner = user; | ||
473 | folder.ID = UUID.Random(); | ||
474 | folder.Name = "Lost And Found"; | ||
475 | folder.Type = (short)AssetType.LostAndFoundFolder; | ||
476 | folder.Version = 1; | ||
477 | Folders.Add(folder.ID, folder); | ||
478 | |||
479 | folder = new InventoryFolderBase(); | ||
480 | folder.ParentID = rootFolder; | ||
481 | folder.Owner = user; | ||
482 | folder.ID = UUID.Random(); | ||
483 | folder.Name = "Notecards"; | ||
484 | folder.Type = (short)AssetType.Notecard; | ||
485 | folder.Version = 1; | ||
486 | Folders.Add(folder.ID, folder); | ||
487 | |||
488 | folder = new InventoryFolderBase(); | ||
489 | folder.ParentID = rootFolder; | ||
490 | folder.Owner = user; | ||
491 | folder.ID = UUID.Random(); | ||
492 | folder.Name = "Objects"; | ||
493 | folder.Type = (short)AssetType.Object; | ||
494 | folder.Version = 1; | ||
495 | Folders.Add(folder.ID, folder); | ||
496 | |||
497 | folder = new InventoryFolderBase(); | ||
498 | folder.ParentID = rootFolder; | ||
499 | folder.Owner = user; | ||
500 | folder.ID = UUID.Random(); | ||
501 | folder.Name = "Photo Album"; | ||
502 | folder.Type = (short)AssetType.SnapshotFolder; | ||
503 | folder.Version = 1; | ||
504 | Folders.Add(folder.ID, folder); | ||
505 | |||
506 | folder = new InventoryFolderBase(); | ||
507 | folder.ParentID = rootFolder; | ||
508 | folder.Owner = user; | ||
509 | folder.ID = UUID.Random(); | ||
510 | folder.Name = "Scripts"; | ||
511 | folder.Type = (short)AssetType.LSLText; | ||
512 | folder.Version = 1; | ||
513 | Folders.Add(folder.ID, folder); | ||
514 | |||
515 | folder = new InventoryFolderBase(); | ||
516 | folder.ParentID = rootFolder; | ||
517 | folder.Owner = user; | ||
518 | folder.ID = UUID.Random(); | ||
519 | folder.Name = "Sounds"; | ||
520 | folder.Type = (short)AssetType.Sound; | ||
521 | folder.Version = 1; | ||
522 | Folders.Add(folder.ID, folder); | ||
523 | |||
524 | folder = new InventoryFolderBase(); | ||
525 | folder.ParentID = rootFolder; | ||
526 | folder.Owner = user; | ||
527 | folder.ID = UUID.Random(); | ||
528 | folder.Name = "Textures"; | ||
529 | folder.Type = (short)AssetType.Texture; | ||
530 | folder.Version = 1; | ||
531 | Folders.Add(folder.ID, folder); | ||
532 | |||
533 | folder = new InventoryFolderBase(); | ||
534 | folder.ParentID = rootFolder; | ||
535 | folder.Owner = user; | ||
536 | folder.ID = UUID.Random(); | ||
537 | folder.Name = "Trash"; | ||
538 | folder.Type = (short)AssetType.TrashFolder; | ||
539 | folder.Version = 1; | ||
540 | Folders.Add(folder.ID, folder); | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | } | ||
diff --git a/OpenSim/Services/InventoryService/InventoryServiceBase.cs b/OpenSim/Services/InventoryService/InventoryServiceBase.cs new file mode 100644 index 0000000..a10e94f --- /dev/null +++ b/OpenSim/Services/InventoryService/InventoryServiceBase.cs | |||
@@ -0,0 +1,98 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using Nini.Config; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Data; | ||
34 | using OpenSim.Services.Interfaces; | ||
35 | using OpenSim.Services.Base; | ||
36 | |||
37 | namespace OpenSim.Services.InventoryService | ||
38 | { | ||
39 | public class InventoryServiceBase : ServiceBase | ||
40 | { | ||
41 | protected IInventoryDataPlugin m_Database = null; | ||
42 | |||
43 | protected List<IInventoryDataPlugin> m_plugins = new List<IInventoryDataPlugin>(); | ||
44 | |||
45 | public InventoryServiceBase(IConfigSource config) : base(config) | ||
46 | { | ||
47 | IConfig assetConfig = config.Configs["InventoryService"]; | ||
48 | if (assetConfig == null) | ||
49 | throw new Exception("No InventoryService configuration"); | ||
50 | |||
51 | string dllName = assetConfig.GetString("StorageProvider", | ||
52 | String.Empty); | ||
53 | |||
54 | if (dllName == String.Empty) | ||
55 | throw new Exception("No StorageProvider configured"); | ||
56 | |||
57 | string connString = assetConfig.GetString("ConnectionString", | ||
58 | String.Empty); | ||
59 | |||
60 | m_Database = LoadPlugin<IInventoryDataPlugin>(dllName); | ||
61 | if (m_Database == null) | ||
62 | throw new Exception("Could not find a storage interface in the given module"); | ||
63 | |||
64 | m_Database.Initialise(connString); | ||
65 | |||
66 | } | ||
67 | |||
68 | #region Plugin methods | ||
69 | |||
70 | /// <summary> | ||
71 | /// Add a new inventory data plugin - plugins will be requested in the order they were added. | ||
72 | /// </summary> | ||
73 | /// <param name="plugin">The plugin that will provide data</param> | ||
74 | public void AddPlugin(IInventoryDataPlugin plugin) | ||
75 | { | ||
76 | m_plugins.Add(plugin); | ||
77 | } | ||
78 | |||
79 | /// <summary> | ||
80 | /// Adds a list of inventory data plugins, as described by `provider' | ||
81 | /// and `connect', to `m_plugins'. | ||
82 | /// </summary> | ||
83 | /// <param name="provider"> | ||
84 | /// The filename of the inventory server plugin DLL. | ||
85 | /// </param> | ||
86 | /// <param name="connect"> | ||
87 | /// The connection string for the storage backend. | ||
88 | /// </param> | ||
89 | public void AddPlugin(string provider, string connect) | ||
90 | { | ||
91 | m_plugins.AddRange(DataPluginFactory.LoadDataPlugins<IInventoryDataPlugin>(provider, connect)); | ||
92 | } | ||
93 | |||
94 | #endregion | ||
95 | |||
96 | |||
97 | } | ||
98 | } | ||
diff --git a/prebuild.xml b/prebuild.xml index 94d5cdc..9e6b686 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -1392,6 +1392,37 @@ | |||
1392 | </Files> | 1392 | </Files> |
1393 | </Project> | 1393 | </Project> |
1394 | 1394 | ||
1395 | <Project name="OpenSim.Services.InventoryService" path="OpenSim/Services/InventoryService" type="Library"> | ||
1396 | <Configuration name="Debug"> | ||
1397 | <Options> | ||
1398 | <OutputPath>../../../bin/</OutputPath> | ||
1399 | </Options> | ||
1400 | </Configuration> | ||
1401 | <Configuration name="Release"> | ||
1402 | <Options> | ||
1403 | <OutputPath>../../../bin/</OutputPath> | ||
1404 | </Options> | ||
1405 | </Configuration> | ||
1406 | |||
1407 | <ReferencePath>../../../bin/</ReferencePath> | ||
1408 | <Reference name="System"/> | ||
1409 | <Reference name="OpenMetaverseTypes.dll"/> | ||
1410 | <Reference name="OpenMetaverse.dll"/> | ||
1411 | <Reference name="OpenSim.Framework"/> | ||
1412 | <Reference name="OpenSim.Framework.Console"/> | ||
1413 | <Reference name="OpenSim.Framework.Servers.HttpServer"/> | ||
1414 | <Reference name="OpenSim.Services.Interfaces"/> | ||
1415 | <Reference name="OpenSim.Services.Base"/> | ||
1416 | <Reference name="OpenSim.Services.Connectors"/> | ||
1417 | <Reference name="OpenSim.Data"/> | ||
1418 | <Reference name="Nini.dll" /> | ||
1419 | <Reference name="log4net.dll"/> | ||
1420 | |||
1421 | <Files> | ||
1422 | <Match pattern="*.cs" recurse="true"/> | ||
1423 | </Files> | ||
1424 | </Project> | ||
1425 | |||
1395 | <Project name="OpenSim.Server.Base" path="OpenSim/Server/Base" type="Library"> | 1426 | <Project name="OpenSim.Server.Base" path="OpenSim/Server/Base" type="Library"> |
1396 | <Configuration name="Debug"> | 1427 | <Configuration name="Debug"> |
1397 | <Options> | 1428 | <Options> |