aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Scripting
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting')
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs171
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs391
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs155
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs307
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs901
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs82
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs6
7 files changed, 1834 insertions, 179 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
new file mode 100755
index 0000000..6009dc5
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -0,0 +1,171 @@
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 copyrightD
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 */
27using System;
28using System.Collections.Generic;
29using System.Linq;
30using System.Reflection;
31using System.Text;
32
33using OpenSim.Framework;
34using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.CoreModules;
38
39using Mono.Addins;
40using Nini.Config;
41using log4net;
42using OpenMetaverse;
43
44namespace OpenSim.Region.OptionalModules.Scripting
45{
46[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
47public class ExtendedPhysics : INonSharedRegionModule
48{
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 private static string LogHeader = "[EXTENDED PHYSICS]";
51
52 private IConfig Configuration { get; set; }
53 private bool Enabled { get; set; }
54 private Scene BaseScene { get; set; }
55 private IScriptModuleComms Comms { get; set; }
56
57 #region INonSharedRegionModule
58
59 public string Name { get { return this.GetType().Name; } }
60
61 public void Initialise(IConfigSource config)
62 {
63 BaseScene = null;
64 Enabled = false;
65 Configuration = null;
66 Comms = null;
67
68 try
69 {
70 if ((Configuration = config.Configs["ExtendedPhysics"]) != null)
71 {
72 Enabled = Configuration.GetBoolean("Enabled", Enabled);
73 }
74 }
75 catch (Exception e)
76 {
77 m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e);
78 }
79
80 m_log.InfoFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not"));
81 }
82
83 public void Close()
84 {
85 if (BaseScene != null)
86 {
87 BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene;
88 BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated;
89 BaseScene = null;
90 }
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 }
96
97 public void RemoveRegion(Scene scene)
98 {
99 if (BaseScene != null && BaseScene == scene)
100 {
101 Close();
102 }
103 }
104
105 public void RegionLoaded(Scene scene)
106 {
107 if (!Enabled) return;
108
109 BaseScene = scene;
110
111 Comms = BaseScene.RequestModuleInterface<IScriptModuleComms>();
112 if (Comms == null)
113 {
114 m_log.WarnFormat("{0} ScriptModuleComms interface not defined", LogHeader);
115 Enabled = false;
116
117 return;
118 }
119
120 // Register as LSL functions all the [ScriptInvocation] marked methods.
121 Comms.RegisterScriptInvocations(this);
122
123 // When an object is modified, we might need to update its extended physics parameters
124 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
125 BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated;
126
127 }
128
129 public Type ReplaceableInterface { get { return null; } }
130
131 #endregion // INonSharedRegionModule
132
133 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
134 {
135 throw new NotImplementedException();
136 }
137
138 // Event generated when some property of a prim changes.
139 private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate)
140 {
141 }
142
143 [ScriptConstant]
144 public static int PHYS_CENTER_OF_MASS = 1 << 0;
145
146 [ScriptConstant]
147 public static int PHYS_LINKSET_TYPE_CONSTRAINT = 1;
148 [ScriptConstant]
149 public static int PHYS_LINKSET_TYPE_COMPOUND = 2;
150 [ScriptConstant]
151 public static int PHYS_LINKSET_TYPE_MANUAL = 3;
152
153 [ScriptInvocation]
154 public string physGetEngineType(UUID hostID, UUID scriptID)
155 {
156 string ret = string.Empty;
157
158 if (BaseScene.PhysicsScene != null)
159 {
160 ret = BaseScene.PhysicsScene.EngineType;
161 }
162
163 return ret;
164 }
165
166 [ScriptInvocation]
167 public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
168 {
169 }
170}
171}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
index 34894ba..e498c6a 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
49 private static readonly ILog m_log = 49 private static readonly ILog m_log =
50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private OSD m_ValueStore; 52 protected virtual OSD ValueStore { get; set; }
53 53
54 protected class TakeValueCallbackClass 54 protected class TakeValueCallbackClass
55 { 55 {
@@ -68,42 +68,141 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
68 protected List<TakeValueCallbackClass> m_TakeStore; 68 protected List<TakeValueCallbackClass> m_TakeStore;
69 protected List<TakeValueCallbackClass> m_ReadStore; 69 protected List<TakeValueCallbackClass> m_ReadStore;
70 70
71 // add separators for quoted paths and array references
72 protected static Regex m_ParsePassOne = new Regex("({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])");
71 73
74 // add quotes to bare identifiers which are limited to alphabetic characters
75 protected static Regex m_ParsePassThree = new Regex("(?<!{[^}]*)\\.([a-zA-Z]+)(?=\\.)");
76
77 // remove extra separator characters
78 protected static Regex m_ParsePassFour = new Regex("\\.+");
79
80 // expression used to validate the full path, this is canonical representation
81 protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$");
82
83 // expression used to match path components
84 protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])");
85
86 // extract the internals of an array reference
87 protected static Regex m_SimpleArrayPattern = new Regex("^\\[([0-9]+)\\]$");
88 protected static Regex m_ArrayPattern = new Regex("^\\[([0-9]+|\\+)\\]$");
89
90 // extract the internals of a has reference
91 protected static Regex m_HashPattern = new Regex("^{([^}]+)}$");
92
93 // -----------------------------------------------------------------
94 /// <summary>
95 /// This is a simple estimator for the size of the stored data, it
96 /// is not precise, but should be close enough to implement reasonable
97 /// limits on the storage space used
98 /// </summary>
99 // -----------------------------------------------------------------
100 public int StringSpace { get; set; }
101
72 // ----------------------------------------------------------------- 102 // -----------------------------------------------------------------
73 /// <summary> 103 /// <summary>
74 /// 104 ///
75 /// </summary> 105 /// </summary>
76 // ----------------------------------------------------------------- 106 // -----------------------------------------------------------------
77 public JsonStore() : this("") {} 107 public static bool CanonicalPathExpression(string ipath, out string opath)
108 {
109 Stack<string> path;
110 if (! ParsePathExpression(ipath,out path))
111 {
112 opath = "";
113 return false;
114 }
115
116 opath = PathExpressionToKey(path);
117 return true;
118 }
78 119
79 public JsonStore(string value) 120 // -----------------------------------------------------------------
121 /// <summary>
122 ///
123 /// </summary>
124 // -----------------------------------------------------------------
125 public JsonStore()
80 { 126 {
127 StringSpace = 0;
81 m_TakeStore = new List<TakeValueCallbackClass>(); 128 m_TakeStore = new List<TakeValueCallbackClass>();
82 m_ReadStore = new List<TakeValueCallbackClass>(); 129 m_ReadStore = new List<TakeValueCallbackClass>();
83 130 }
131
132 public JsonStore(string value) : this()
133 {
134 // This is going to throw an exception if the value is not
135 // a valid JSON chunk. Calling routines should catch the
136 // exception and handle it appropriately
84 if (String.IsNullOrEmpty(value)) 137 if (String.IsNullOrEmpty(value))
85 m_ValueStore = new OSDMap(); 138 ValueStore = new OSDMap();
86 else 139 else
87 m_ValueStore = OSDParser.DeserializeJson(value); 140 ValueStore = OSDParser.DeserializeJson(value);
88 } 141 }
142
143 // -----------------------------------------------------------------
144 /// <summary>
145 ///
146 /// </summary>
147 // -----------------------------------------------------------------
148 public JsonStoreNodeType GetNodeType(string expr)
149 {
150 Stack<string> path;
151 if (! ParsePathExpression(expr,out path))
152 return JsonStoreNodeType.Undefined;
153
154 OSD result = ProcessPathExpression(ValueStore,path);
89 155
156 if (result == null)
157 return JsonStoreNodeType.Undefined;
158
159 if (result is OSDMap)
160 return JsonStoreNodeType.Object;
161
162 if (result is OSDArray)
163 return JsonStoreNodeType.Array;
164
165 if (OSDBaseType(result.Type))
166 return JsonStoreNodeType.Value;
167
168 return JsonStoreNodeType.Undefined;
169 }
170
90 // ----------------------------------------------------------------- 171 // -----------------------------------------------------------------
91 /// <summary> 172 /// <summary>
92 /// 173 ///
93 /// </summary> 174 /// </summary>
94 // ----------------------------------------------------------------- 175 // -----------------------------------------------------------------
95 public bool TestPath(string expr, bool useJson) 176 public JsonStoreValueType GetValueType(string expr)
96 { 177 {
97 Stack<string> path = ParsePathExpression(expr); 178 Stack<string> path;
98 OSD result = ProcessPathExpression(m_ValueStore,path); 179 if (! ParsePathExpression(expr,out path))
180 return JsonStoreValueType.Undefined;
181
182 OSD result = ProcessPathExpression(ValueStore,path);
99 183
100 if (result == null) 184 if (result == null)
101 return false; 185 return JsonStoreValueType.Undefined;
102 186
103 if (useJson || result.Type == OSDType.String) 187 if (result is OSDMap)
104 return true; 188 return JsonStoreValueType.Undefined;
105 189
106 return false; 190 if (result is OSDArray)
191 return JsonStoreValueType.Undefined;
192
193 if (result is OSDBoolean)
194 return JsonStoreValueType.Boolean;
195
196 if (result is OSDInteger)
197 return JsonStoreValueType.Integer;
198
199 if (result is OSDReal)
200 return JsonStoreValueType.Float;
201
202 if (result is OSDString)
203 return JsonStoreValueType.String;
204
205 return JsonStoreValueType.Undefined;
107 } 206 }
108 207
109 // ----------------------------------------------------------------- 208 // -----------------------------------------------------------------
@@ -111,10 +210,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
111 /// 210 ///
112 /// </summary> 211 /// </summary>
113 // ----------------------------------------------------------------- 212 // -----------------------------------------------------------------
213 public int ArrayLength(string expr)
214 {
215 Stack<string> path;
216 if (! ParsePathExpression(expr,out path))
217 return -1;
218
219 OSD result = ProcessPathExpression(ValueStore,path);
220 if (result != null && result.Type == OSDType.Array)
221 {
222 OSDArray arr = result as OSDArray;
223 return arr.Count;
224 }
225
226 return -1;
227 }
228
229 // -----------------------------------------------------------------
230 /// <summary>
231 ///
232 /// </summary>
233 // -----------------------------------------------------------------
114 public bool GetValue(string expr, out string value, bool useJson) 234 public bool GetValue(string expr, out string value, bool useJson)
115 { 235 {
116 Stack<string> path = ParsePathExpression(expr); 236 Stack<string> path;
117 OSD result = ProcessPathExpression(m_ValueStore,path); 237 if (! ParsePathExpression(expr,out path))
238 {
239 value = "";
240 return false;
241 }
242
243 OSD result = ProcessPathExpression(ValueStore,path);
118 return ConvertOutputValue(result,out value,useJson); 244 return ConvertOutputValue(result,out value,useJson);
119 } 245 }
120 246
@@ -136,7 +262,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
136 // ----------------------------------------------------------------- 262 // -----------------------------------------------------------------
137 public bool SetValue(string expr, string value, bool useJson) 263 public bool SetValue(string expr, string value, bool useJson)
138 { 264 {
139 OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value); 265 OSD ovalue;
266
267 // One note of caution... if you use an empty string in the
268 // structure it will be assumed to be a default value and will
269 // not be seialized in the json
270
271 if (useJson)
272 {
273 // There doesn't appear to be a good way to determine if the
274 // value is valid Json other than to let the parser crash
275 try
276 {
277 ovalue = OSDParser.DeserializeJson(value);
278 }
279 catch (Exception e)
280 {
281 if (value.StartsWith("'") && value.EndsWith("'"))
282 {
283 ovalue = new OSDString(value.Substring(1,value.Length - 2));
284 }
285 else
286 {
287 return false;
288 }
289 }
290 }
291 else
292 {
293 ovalue = new OSDString(value);
294 }
295
140 return SetValueFromExpression(expr,ovalue); 296 return SetValueFromExpression(expr,ovalue);
141 } 297 }
142 298
@@ -147,10 +303,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
147 // ----------------------------------------------------------------- 303 // -----------------------------------------------------------------
148 public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) 304 public bool TakeValue(string expr, bool useJson, TakeValueCallback cback)
149 { 305 {
150 Stack<string> path = ParsePathExpression(expr); 306 Stack<string> path;
307 if (! ParsePathExpression(expr,out path))
308 return false;
309
151 string pexpr = PathExpressionToKey(path); 310 string pexpr = PathExpressionToKey(path);
152 311
153 OSD result = ProcessPathExpression(m_ValueStore,path); 312 OSD result = ProcessPathExpression(ValueStore,path);
154 if (result == null) 313 if (result == null)
155 { 314 {
156 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); 315 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
@@ -178,10 +337,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
178 // ----------------------------------------------------------------- 337 // -----------------------------------------------------------------
179 public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) 338 public bool ReadValue(string expr, bool useJson, TakeValueCallback cback)
180 { 339 {
181 Stack<string> path = ParsePathExpression(expr); 340 Stack<string> path;
341 if (! ParsePathExpression(expr,out path))
342 return false;
343
182 string pexpr = PathExpressionToKey(path); 344 string pexpr = PathExpressionToKey(path);
183 345
184 OSD result = ProcessPathExpression(m_ValueStore,path); 346 OSD result = ProcessPathExpression(ValueStore,path);
185 if (result == null) 347 if (result == null)
186 { 348 {
187 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); 349 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
@@ -208,25 +370,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
208 // ----------------------------------------------------------------- 370 // -----------------------------------------------------------------
209 protected bool SetValueFromExpression(string expr, OSD ovalue) 371 protected bool SetValueFromExpression(string expr, OSD ovalue)
210 { 372 {
211 Stack<string> path = ParsePathExpression(expr); 373 Stack<string> path;
374 if (! ParsePathExpression(expr,out path))
375 return false;
376
212 if (path.Count == 0) 377 if (path.Count == 0)
213 { 378 {
214 m_ValueStore = ovalue; 379 ValueStore = ovalue;
380 StringSpace = 0;
215 return true; 381 return true;
216 } 382 }
217 383
384 // pkey will be the final element in the path, we pull it out here to make sure
385 // that the assignment works correctly
218 string pkey = path.Pop(); 386 string pkey = path.Pop();
219 string pexpr = PathExpressionToKey(path); 387 string pexpr = PathExpressionToKey(path);
220 if (pexpr != "") 388 if (pexpr != "")
221 pexpr += "."; 389 pexpr += ".";
222 390
223 OSD result = ProcessPathExpression(m_ValueStore,path); 391 OSD result = ProcessPathExpression(ValueStore,path);
224 if (result == null) 392 if (result == null)
225 return false; 393 return false;
226 394
227 Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]"); 395 // Check pkey, the last element in the path, for and extract array references
228 MatchCollection amatches = aPattern.Matches(pkey,0); 396 MatchCollection amatches = m_ArrayPattern.Matches(pkey,0);
229
230 if (amatches.Count > 0) 397 if (amatches.Count > 0)
231 { 398 {
232 if (result.Type != OSDType.Array) 399 if (result.Type != OSDType.Array)
@@ -242,8 +409,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
242 { 409 {
243 string npkey = String.Format("[{0}]",amap.Count); 410 string npkey = String.Format("[{0}]",amap.Count);
244 411
245 amap.Add(ovalue); 412 if (ovalue != null)
246 InvokeNextCallback(pexpr + npkey); 413 {
414 StringSpace += ComputeSizeOf(ovalue);
415
416 amap.Add(ovalue);
417 InvokeNextCallback(pexpr + npkey);
418 }
247 return true; 419 return true;
248 } 420 }
249 421
@@ -251,9 +423,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
251 if (0 <= aval && aval < amap.Count) 423 if (0 <= aval && aval < amap.Count)
252 { 424 {
253 if (ovalue == null) 425 if (ovalue == null)
426 {
427 StringSpace -= ComputeSizeOf(amap[aval]);
254 amap.RemoveAt(aval); 428 amap.RemoveAt(aval);
429 }
255 else 430 else
256 { 431 {
432 StringSpace -= ComputeSizeOf(amap[aval]);
433 StringSpace += ComputeSizeOf(ovalue);
257 amap[aval] = ovalue; 434 amap[aval] = ovalue;
258 InvokeNextCallback(pexpr + pkey); 435 InvokeNextCallback(pexpr + pkey);
259 } 436 }
@@ -263,9 +440,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
263 return false; 440 return false;
264 } 441 }
265 442
266 Regex hPattern = new Regex("{([^}]+)}"); 443 // Check for and extract hash references
267 MatchCollection hmatches = hPattern.Matches(pkey,0); 444 MatchCollection hmatches = m_HashPattern.Matches(pkey,0);
268
269 if (hmatches.Count > 0) 445 if (hmatches.Count > 0)
270 { 446 {
271 Match match = hmatches[0]; 447 Match match = hmatches[0];
@@ -274,16 +450,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
274 450
275 if (result is OSDMap) 451 if (result is OSDMap)
276 { 452 {
453 // this is the assignment case
277 OSDMap hmap = result as OSDMap; 454 OSDMap hmap = result as OSDMap;
278 if (ovalue != null) 455 if (ovalue != null)
279 { 456 {
457 StringSpace -= ComputeSizeOf(hmap[hkey]);
458 StringSpace += ComputeSizeOf(ovalue);
459
280 hmap[hkey] = ovalue; 460 hmap[hkey] = ovalue;
281 InvokeNextCallback(pexpr + pkey); 461 InvokeNextCallback(pexpr + pkey);
462 return true;
282 } 463 }
283 else if (hmap.ContainsKey(hkey)) 464
465 // this is the remove case
466 if (hmap.ContainsKey(hkey))
467 {
468 StringSpace -= ComputeSizeOf(hmap[hkey]);
284 hmap.Remove(hkey); 469 hmap.Remove(hkey);
285 470 return true;
286 return true; 471 }
472
473 return false;
287 } 474 }
288 475
289 return false; 476 return false;
@@ -332,39 +519,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
332 /// use a stack because we process the path in inverse order later 519 /// use a stack because we process the path in inverse order later
333 /// </summary> 520 /// </summary>
334 // ----------------------------------------------------------------- 521 // -----------------------------------------------------------------
335 protected static Stack<string> ParsePathExpression(string path) 522 protected static bool ParsePathExpression(string expr, out Stack<string> path)
336 { 523 {
337 Stack<string> m_path = new Stack<string>(); 524 path = new Stack<string>();
338 525
339 // add front and rear separators 526 // add front and rear separators
340 path = "." + path + "."; 527 expr = "." + expr + ".";
341 528
342 // add separators for quoted paths 529 // add separators for quoted exprs and array references
343 Regex pass1 = new Regex("{[^}]+}"); 530 expr = m_ParsePassOne.Replace(expr,".$1.",-1,0);
344 path = pass1.Replace(path,".$0.",-1,0);
345
346 // add separators for array references
347 Regex pass2 = new Regex("(\\[[0-9]+\\]|\\[\\+\\])");
348 path = pass2.Replace(path,".$0.",-1,0);
349 531
350 // add quotes to bare identifier 532 // add quotes to bare identifier
351 Regex pass3 = new Regex("\\.([a-zA-Z]+)"); 533 expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0);
352 path = pass3.Replace(path,".{$1}",-1,0);
353 534
354 // remove extra separators 535 // remove extra separators
355 Regex pass4 = new Regex("\\.+"); 536 expr = m_ParsePassFour.Replace(expr,".",-1,0);
356 path = pass4.Replace(path,".",-1,0);
357 537
358 Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); 538 // validate the results (catches extra quote characters for example)
359 if (validate.IsMatch(path)) 539 if (m_ValidatePath.IsMatch(expr))
360 { 540 {
361 Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); 541 MatchCollection matches = m_PathComponent.Matches(expr,0);
362 MatchCollection matches = parser.Matches(path,0);
363 foreach (Match match in matches) 542 foreach (Match match in matches)
364 m_path.Push(match.Groups[1].Value); 543 path.Push(match.Groups[1].Value);
544
545 return true;
365 } 546 }
366 547
367 return m_path; 548 return false;
368 } 549 }
369 550
370 // ----------------------------------------------------------------- 551 // -----------------------------------------------------------------
@@ -385,9 +566,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
385 return null; 566 return null;
386 567
387 // ---------- Check for an array index ---------- 568 // ---------- Check for an array index ----------
388 Regex aPattern = new Regex("\\[([0-9]+)\\]"); 569 MatchCollection amatches = m_SimpleArrayPattern.Matches(pkey,0);
389 MatchCollection amatches = aPattern.Matches(pkey,0); 570
390
391 if (amatches.Count > 0) 571 if (amatches.Count > 0)
392 { 572 {
393 if (rmap.Type != OSDType.Array) 573 if (rmap.Type != OSDType.Array)
@@ -410,9 +590,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
410 } 590 }
411 591
412 // ---------- Check for a hash index ---------- 592 // ---------- Check for a hash index ----------
413 Regex hPattern = new Regex("{([^}]+)}"); 593 MatchCollection hmatches = m_HashPattern.Matches(pkey,0);
414 MatchCollection hmatches = hPattern.Matches(pkey,0); 594
415
416 if (hmatches.Count > 0) 595 if (hmatches.Count > 0)
417 { 596 {
418 if (rmap.Type != OSDType.Map) 597 if (rmap.Type != OSDType.Map)
@@ -456,14 +635,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
456 // The path pointed to an intermediate hash structure 635 // The path pointed to an intermediate hash structure
457 if (result.Type == OSDType.Map) 636 if (result.Type == OSDType.Map)
458 { 637 {
459 value = OSDParser.SerializeJsonString(result as OSDMap); 638 value = OSDParser.SerializeJsonString(result as OSDMap,true);
460 return true; 639 return true;
461 } 640 }
462 641
463 // The path pointed to an intermediate hash structure 642 // The path pointed to an intermediate hash structure
464 if (result.Type == OSDType.Array) 643 if (result.Type == OSDType.Array)
465 { 644 {
466 value = OSDParser.SerializeJsonString(result as OSDArray); 645 value = OSDParser.SerializeJsonString(result as OSDArray,true);
467 return true; 646 return true;
468 } 647 }
469 648
@@ -471,7 +650,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
471 return true; 650 return true;
472 } 651 }
473 652
474 if (result.Type == OSDType.String) 653 if (OSDBaseType(result.Type))
475 { 654 {
476 value = result.AsString(); 655 value = result.AsString();
477 return true; 656 return true;
@@ -496,5 +675,91 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
496 675
497 return pkey; 676 return pkey;
498 } 677 }
678
679 // -----------------------------------------------------------------
680 /// <summary>
681 ///
682 /// </summary>
683 // -----------------------------------------------------------------
684 protected static bool OSDBaseType(OSDType type)
685 {
686 // Should be the list of base types for which AsString() returns
687 // something useful
688 if (type == OSDType.Boolean)
689 return true;
690 if (type == OSDType.Integer)
691 return true;
692 if (type == OSDType.Real)
693 return true;
694 if (type == OSDType.String)
695 return true;
696 if (type == OSDType.UUID)
697 return true;
698 if (type == OSDType.Date)
699 return true;
700 if (type == OSDType.URI)
701 return true;
702
703 return false;
704 }
705
706 // -----------------------------------------------------------------
707 /// <summary>
708 ///
709 /// </summary>
710 // -----------------------------------------------------------------
711 protected static int ComputeSizeOf(OSD value)
712 {
713 string sval;
714
715 if (ConvertOutputValue(value,out sval,true))
716 return sval.Length;
717
718 return 0;
719 }
720 }
721
722 // -----------------------------------------------------------------
723 /// <summary>
724 /// </summary>
725 // -----------------------------------------------------------------
726 public class JsonObjectStore : JsonStore
727 {
728 private static readonly ILog m_log =
729 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
730
731 private Scene m_scene;
732 private UUID m_objectID;
733
734 protected override OSD ValueStore
735 {
736 get
737 {
738 SceneObjectPart sop = m_scene.GetSceneObjectPart(m_objectID);
739 if (sop == null)
740 {
741 // This is bad
742 return null;
743 }
744
745 return sop.DynAttrs.TopLevelMap;
746 }
747
748 // cannot set the top level
749 set
750 {
751 m_log.InfoFormat("[JsonStore] cannot set top level value in object store");
752 }
753 }
754
755 public JsonObjectStore(Scene scene, UUID oid) : base()
756 {
757 m_scene = scene;
758 m_objectID = oid;
759
760 // the size limit is imposed on whatever is already in the store
761 StringSpace = ComputeSizeOf(ValueStore);
762 }
499 } 763 }
764
500} 765}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index e68764a..5fbfcc5 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
54 54
55 private IConfig m_config = null; 55 private IConfig m_config = null;
56 private bool m_enabled = false; 56 private bool m_enabled = false;
57 private bool m_enableObjectStore = false;
58 private int m_maxStringSpace = Int32.MaxValue;
59
57 private Scene m_scene = null; 60 private Scene m_scene = null;
58 61
59 private Dictionary<UUID,JsonStore> m_JsonValueStore; 62 private Dictionary<UUID,JsonStore> m_JsonValueStore;
@@ -90,15 +93,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
90 } 93 }
91 94
92 m_enabled = m_config.GetBoolean("Enabled", m_enabled); 95 m_enabled = m_config.GetBoolean("Enabled", m_enabled);
96 m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore);
97 m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace);
98 if (m_maxStringSpace == 0)
99 m_maxStringSpace = Int32.MaxValue;
93 } 100 }
94 catch (Exception e) 101 catch (Exception e)
95 { 102 {
96 m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message); 103 m_log.Error("[JsonStore]: initialization error: {0}", e);
97 return; 104 return;
98 } 105 }
99 106
100 if (m_enabled) 107 if (m_enabled)
101 m_log.DebugFormat("[JsonStore] module is enabled"); 108 m_log.DebugFormat("[JsonStore]: module is enabled");
102 } 109 }
103 110
104 // ----------------------------------------------------------------- 111 // -----------------------------------------------------------------
@@ -175,6 +182,35 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
175 /// 182 ///
176 /// </summary> 183 /// </summary>
177 // ----------------------------------------------------------------- 184 // -----------------------------------------------------------------
185 public bool AttachObjectStore(UUID objectID)
186 {
187 if (! m_enabled) return false;
188 if (! m_enableObjectStore) return false;
189
190 SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
191 if (sop == null)
192 {
193 m_log.ErrorFormat("[JsonStore] unable to attach to unknown object; {0}", objectID);
194 return false;
195 }
196
197 lock (m_JsonValueStore)
198 {
199 if (m_JsonValueStore.ContainsKey(objectID))
200 return true;
201
202 JsonStore map = new JsonObjectStore(m_scene,objectID);
203 m_JsonValueStore.Add(objectID,map);
204 }
205
206 return true;
207 }
208
209 // -----------------------------------------------------------------
210 /// <summary>
211 ///
212 /// </summary>
213 // -----------------------------------------------------------------
178 public bool CreateStore(string value, ref UUID result) 214 public bool CreateStore(string value, ref UUID result)
179 { 215 {
180 if (result == UUID.Zero) 216 if (result == UUID.Zero)
@@ -191,7 +227,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
191 } 227 }
192 catch (Exception e) 228 catch (Exception e)
193 { 229 {
194 m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message); 230 m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value);
195 return false; 231 return false;
196 } 232 }
197 233
@@ -211,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
211 if (! m_enabled) return false; 247 if (! m_enabled) return false;
212 248
213 lock (m_JsonValueStore) 249 lock (m_JsonValueStore)
214 m_JsonValueStore.Remove(storeID); 250 return m_JsonValueStore.Remove(storeID);
215 251
216 return true; 252 return true;
217 } 253 }
@@ -221,31 +257,76 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
221 /// 257 ///
222 /// </summary> 258 /// </summary>
223 // ----------------------------------------------------------------- 259 // -----------------------------------------------------------------
224 public bool TestPath(UUID storeID, string path, bool useJson) 260 public bool TestStore(UUID storeID)
225 { 261 {
226 if (! m_enabled) return false; 262 if (! m_enabled) return false;
227 263
264 lock (m_JsonValueStore)
265 return m_JsonValueStore.ContainsKey(storeID);
266 }
267
268 // -----------------------------------------------------------------
269 /// <summary>
270 ///
271 /// </summary>
272 // -----------------------------------------------------------------
273 public JsonStoreNodeType GetNodeType(UUID storeID, string path)
274 {
275 if (! m_enabled) return JsonStoreNodeType.Undefined;
276
228 JsonStore map = null; 277 JsonStore map = null;
229 lock (m_JsonValueStore) 278 lock (m_JsonValueStore)
230 { 279 {
231 if (! m_JsonValueStore.TryGetValue(storeID,out map)) 280 if (! m_JsonValueStore.TryGetValue(storeID,out map))
232 { 281 {
233 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); 282 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
234 return false; 283 return JsonStoreNodeType.Undefined;
235 } 284 }
236 } 285 }
237 286
238 try 287 try
239 { 288 {
240 lock (map) 289 lock (map)
241 return map.TestPath(path,useJson); 290 return map.GetNodeType(path);
242 } 291 }
243 catch (Exception e) 292 catch (Exception e)
244 { 293 {
245 m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message); 294 m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
246 } 295 }
247 296
248 return false; 297 return JsonStoreNodeType.Undefined;
298 }
299
300 // -----------------------------------------------------------------
301 /// <summary>
302 ///
303 /// </summary>
304 // -----------------------------------------------------------------
305 public JsonStoreValueType GetValueType(UUID storeID, string path)
306 {
307 if (! m_enabled) return JsonStoreValueType.Undefined;
308
309 JsonStore map = null;
310 lock (m_JsonValueStore)
311 {
312 if (! m_JsonValueStore.TryGetValue(storeID,out map))
313 {
314 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
315 return JsonStoreValueType.Undefined;
316 }
317 }
318
319 try
320 {
321 lock (map)
322 return map.GetValueType(path);
323 }
324 catch (Exception e)
325 {
326 m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
327 }
328
329 return JsonStoreValueType.Undefined;
249 } 330 }
250 331
251 // ----------------------------------------------------------------- 332 // -----------------------------------------------------------------
@@ -270,12 +351,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
270 try 351 try
271 { 352 {
272 lock (map) 353 lock (map)
273 if (map.SetValue(path,value,useJson)) 354 {
274 return true; 355 if (map.StringSpace > m_maxStringSpace)
356 {
357 m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
358 storeID,map.StringSpace,m_maxStringSpace);
359 return false;
360 }
361
362 return map.SetValue(path,value,useJson);
363 }
275 } 364 }
276 catch (Exception e) 365 catch (Exception e)
277 { 366 {
278 m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message); 367 m_log.Error(string.Format("[JsonStore]: Unable to assign {0} to {1} in {2}", value, path, storeID), e);
279 } 368 }
280 369
281 return false; 370 return false;
@@ -303,12 +392,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
303 try 392 try
304 { 393 {
305 lock (map) 394 lock (map)
306 if (map.RemoveValue(path)) 395 return map.RemoveValue(path);
307 return true;
308 } 396 }
309 catch (Exception e) 397 catch (Exception e)
310 { 398 {
311 m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message); 399 m_log.Error(string.Format("[JsonStore]: Unable to remove {0} in {1}", path, storeID), e);
312 } 400 }
313 401
314 return false; 402 return false;
@@ -319,6 +407,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
319 /// 407 ///
320 /// </summary> 408 /// </summary>
321 // ----------------------------------------------------------------- 409 // -----------------------------------------------------------------
410 public int GetArrayLength(UUID storeID, string path)
411 {
412 if (! m_enabled) return -1;
413
414 JsonStore map = null;
415 lock (m_JsonValueStore)
416 {
417 if (! m_JsonValueStore.TryGetValue(storeID,out map))
418 return -1;
419 }
420
421 try
422 {
423 lock (map)
424 {
425 return map.ArrayLength(path);
426 }
427 }
428 catch (Exception e)
429 {
430 m_log.Error("[JsonStore]: unable to retrieve value", e);
431 }
432
433 return -1;
434 }
435
436 // -----------------------------------------------------------------
437 /// <summary>
438 ///
439 /// </summary>
440 // -----------------------------------------------------------------
322 public bool GetValue(UUID storeID, string path, bool useJson, out string value) 441 public bool GetValue(UUID storeID, string path, bool useJson, out string value)
323 { 442 {
324 value = String.Empty; 443 value = String.Empty;
@@ -341,7 +460,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
341 } 460 }
342 catch (Exception e) 461 catch (Exception e)
343 { 462 {
344 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message); 463 m_log.Error("[JsonStore]: unable to retrieve value", e);
345 } 464 }
346 465
347 return false; 466 return false;
@@ -380,7 +499,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
380 } 499 }
381 catch (Exception e) 500 catch (Exception e)
382 { 501 {
383 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); 502 m_log.Error("[JsonStore] unable to retrieve value", e);
384 } 503 }
385 504
386 cback(String.Empty); 505 cback(String.Empty);
@@ -419,7 +538,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
419 } 538 }
420 catch (Exception e) 539 catch (Exception e)
421 { 540 {
422 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); 541 m_log.Error("[JsonStore]: unable to retrieve value", e);
423 } 542 }
424 543
425 cback(String.Empty); 544 cback(String.Empty);
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index 0c175ca..1bb5aee 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -39,8 +39,10 @@ using OpenMetaverse.StructuredData;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Scripting;
42using System.Collections.Generic; 43using System.Collections.Generic;
43using System.Text.RegularExpressions; 44using System.Text.RegularExpressions;
45using PermissionMask = OpenSim.Framework.PermissionMask;
44 46
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore 47namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
46{ 48{
@@ -92,12 +94,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
92 } 94 }
93 catch (Exception e) 95 catch (Exception e)
94 { 96 {
95 m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message); 97 m_log.ErrorFormat("[JsonStoreScripts]: initialization error: {0}", e.Message);
96 return; 98 return;
97 } 99 }
98 100
99 if (m_enabled) 101 if (m_enabled)
100 m_log.DebugFormat("[JsonStoreScripts] module is enabled"); 102 m_log.DebugFormat("[JsonStoreScripts]: module is enabled");
101 } 103 }
102 104
103 // ----------------------------------------------------------------- 105 // -----------------------------------------------------------------
@@ -150,7 +152,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
150 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>(); 152 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>();
151 if (m_comms == null) 153 if (m_comms == null)
152 { 154 {
153 m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined"); 155 m_log.ErrorFormat("[JsonStoreScripts]: ScriptModuleComms interface not defined");
154 m_enabled = false; 156 m_enabled = false;
155 return; 157 return;
156 } 158 }
@@ -158,40 +160,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
158 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>(); 160 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>();
159 if (m_store == null) 161 if (m_store == null)
160 { 162 {
161 m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined"); 163 m_log.ErrorFormat("[JsonStoreScripts]: JsonModule interface not defined");
162 m_enabled = false; 164 m_enabled = false;
163 return; 165 return;
164 } 166 }
165 167
166 try 168 try
167 { 169 {
168 m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); 170 m_comms.RegisterScriptInvocations(this);
169 m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); 171 m_comms.RegisterConstants(this);
170
171 m_comms.RegisterScriptInvocation(this,"JsonReadNotecard");
172 m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard");
173
174 m_comms.RegisterScriptInvocation(this,"JsonTestPath");
175 m_comms.RegisterScriptInvocation(this,"JsonTestPathJson");
176
177 m_comms.RegisterScriptInvocation(this,"JsonGetValue");
178 m_comms.RegisterScriptInvocation(this,"JsonGetValueJson");
179
180 m_comms.RegisterScriptInvocation(this,"JsonTakeValue");
181 m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson");
182
183 m_comms.RegisterScriptInvocation(this,"JsonReadValue");
184 m_comms.RegisterScriptInvocation(this,"JsonReadValueJson");
185
186 m_comms.RegisterScriptInvocation(this,"JsonSetValue");
187 m_comms.RegisterScriptInvocation(this,"JsonSetValueJson");
188
189 m_comms.RegisterScriptInvocation(this,"JsonRemoveValue");
190 } 172 }
191 catch (Exception e) 173 catch (Exception e)
192 { 174 {
193 // See http://opensimulator.org/mantis/view.php?id=5971 for more information 175 // See http://opensimulator.org/mantis/view.php?id=5971 for more information
194 m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message); 176 m_log.WarnFormat("[JsonStoreScripts]: script method registration failed; {0}", e.Message);
195 m_enabled = false; 177 m_enabled = false;
196 } 178 }
197 } 179 }
@@ -208,23 +190,61 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
208 190
209#endregion 191#endregion
210 192
193#region ScriptConstantsInterface
194
195 [ScriptConstant]
196 public static readonly int JSON_NODETYPE_UNDEF = (int)JsonStoreNodeType.Undefined;
197
198 [ScriptConstant]
199 public static readonly int JSON_NODETYPE_OBJECT = (int)JsonStoreNodeType.Object;
200
201 [ScriptConstant]
202 public static readonly int JSON_NODETYPE_ARRAY = (int)JsonStoreNodeType.Array;
203
204 [ScriptConstant]
205 public static readonly int JSON_NODETYPE_VALUE = (int)JsonStoreNodeType.Value;
206
207 [ScriptConstant]
208 public static readonly int JSON_VALUETYPE_UNDEF = (int)JsonStoreValueType.Undefined;
209
210 [ScriptConstant]
211 public static readonly int JSON_VALUETYPE_BOOLEAN = (int)JsonStoreValueType.Boolean;
212
213 [ScriptConstant]
214 public static readonly int JSON_VALUETYPE_INTEGER = (int)JsonStoreValueType.Integer;
215
216 [ScriptConstant]
217 public static readonly int JSON_VALUETYPE_FLOAT = (int)JsonStoreValueType.Float;
218
219 [ScriptConstant]
220 public static readonly int JSON_VALUETYPE_STRING = (int)JsonStoreValueType.String;
221
222
223#endregion
224
211#region ScriptInvocationInteface 225#region ScriptInvocationInteface
212 // ----------------------------------------------------------------- 226 // -----------------------------------------------------------------
213 /// <summary> 227 /// <summary>
214 /// 228 ///
215 /// </summary> 229 /// </summary>
216 // ----------------------------------------------------------------- 230 // -----------------------------------------------------------------
217 protected void GenerateRuntimeError(string msg) 231 [ScriptInvocation]
232 public UUID JsonAttachObjectStore(UUID hostID, UUID scriptID)
218 { 233 {
219 throw new Exception("JsonStore Runtime Error: " + msg); 234 UUID uuid = UUID.Zero;
235 if (! m_store.AttachObjectStore(hostID))
236 GenerateRuntimeError("Failed to create Json store");
237
238 return hostID;
220 } 239 }
221 240
222 // ----------------------------------------------------------------- 241 // -----------------------------------------------------------------
223 /// <summary> 242 /// <summary>
224 /// 243 ///
225 /// </summary> 244 /// </summary>
226 // ----------------------------------------------------------------- 245 // -----------------------------------------------------------------
227 protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) 246 [ScriptInvocation]
247 public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
228 { 248 {
229 UUID uuid = UUID.Zero; 249 UUID uuid = UUID.Zero;
230 if (! m_store.CreateStore(value, ref uuid)) 250 if (! m_store.CreateStore(value, ref uuid))
@@ -238,7 +258,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
238 /// 258 ///
239 /// </summary> 259 /// </summary>
240 // ----------------------------------------------------------------- 260 // -----------------------------------------------------------------
241 protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) 261 [ScriptInvocation]
262 public int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID)
242 { 263 {
243 return m_store.DestroyStore(storeID) ? 1 : 0; 264 return m_store.DestroyStore(storeID) ? 1 : 0;
244 } 265 }
@@ -248,10 +269,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
248 /// 269 ///
249 /// </summary> 270 /// </summary>
250 // ----------------------------------------------------------------- 271 // -----------------------------------------------------------------
251 protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) 272 [ScriptInvocation]
273 public int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID)
274 {
275 return m_store.TestStore(storeID) ? 1 : 0;
276 }
277
278 // -----------------------------------------------------------------
279 /// <summary>
280 ///
281 /// </summary>
282 // -----------------------------------------------------------------
283 [ScriptInvocation]
284 public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
252 { 285 {
253 UUID reqID = UUID.Random(); 286 UUID reqID = UUID.Random();
254 Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); 287 Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier));
255 return reqID; 288 return reqID;
256 } 289 }
257 290
@@ -260,7 +293,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
260 /// 293 ///
261 /// </summary> 294 /// </summary>
262 // ----------------------------------------------------------------- 295 // -----------------------------------------------------------------
263 protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) 296 [ScriptInvocation]
297 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
264 { 298 {
265 UUID reqID = UUID.Random(); 299 UUID reqID = UUID.Random();
266 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); 300 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); });
@@ -272,14 +306,41 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
272 /// 306 ///
273 /// </summary> 307 /// </summary>
274 // ----------------------------------------------------------------- 308 // -----------------------------------------------------------------
275 protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) 309 [ScriptInvocation]
310 public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist)
276 { 311 {
277 return m_store.TestPath(storeID,path,false) ? 1 : 0; 312 string ipath = ConvertList2Path(pathlist);
313 string opath;
314
315 if (JsonStore.CanonicalPathExpression(ipath,out opath))
316 return opath;
317
318 // This won't parse if passed to the other routines as opposed to
319 // returning an empty string which is a valid path and would overwrite
320 // the entire store
321 return "**INVALID**";
322 }
323
324 // -----------------------------------------------------------------
325 /// <summary>
326 ///
327 /// </summary>
328 // -----------------------------------------------------------------
329 [ScriptInvocation]
330 public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path)
331 {
332 return (int)m_store.GetNodeType(storeID,path);
278 } 333 }
279 334
280 protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) 335 // -----------------------------------------------------------------
336 /// <summary>
337 ///
338 /// </summary>
339 // -----------------------------------------------------------------
340 [ScriptInvocation]
341 public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path)
281 { 342 {
282 return m_store.TestPath(storeID,path,true) ? 1 : 0; 343 return (int)m_store.GetValueType(storeID,path);
283 } 344 }
284 345
285 // ----------------------------------------------------------------- 346 // -----------------------------------------------------------------
@@ -287,12 +348,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
287 /// 348 ///
288 /// </summary> 349 /// </summary>
289 // ----------------------------------------------------------------- 350 // -----------------------------------------------------------------
290 protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) 351 [ScriptInvocation]
352 public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
291 { 353 {
292 return m_store.SetValue(storeID,path,value,false) ? 1 : 0; 354 return m_store.SetValue(storeID,path,value,false) ? 1 : 0;
293 } 355 }
294 356
295 protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) 357 [ScriptInvocation]
358 public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
296 { 359 {
297 return m_store.SetValue(storeID,path,value,true) ? 1 : 0; 360 return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
298 } 361 }
@@ -302,7 +365,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
302 /// 365 ///
303 /// </summary> 366 /// </summary>
304 // ----------------------------------------------------------------- 367 // -----------------------------------------------------------------
305 protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) 368 [ScriptInvocation]
369 public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path)
306 { 370 {
307 return m_store.RemoveValue(storeID,path) ? 1 : 0; 371 return m_store.RemoveValue(storeID,path) ? 1 : 0;
308 } 372 }
@@ -312,14 +376,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
312 /// 376 ///
313 /// </summary> 377 /// </summary>
314 // ----------------------------------------------------------------- 378 // -----------------------------------------------------------------
315 protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) 379 [ScriptInvocation]
380 public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path)
381 {
382 return m_store.GetArrayLength(storeID,path);
383 }
384
385 // -----------------------------------------------------------------
386 /// <summary>
387 ///
388 /// </summary>
389 // -----------------------------------------------------------------
390 [ScriptInvocation]
391 public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path)
316 { 392 {
317 string value = String.Empty; 393 string value = String.Empty;
318 m_store.GetValue(storeID,path,false,out value); 394 m_store.GetValue(storeID,path,false,out value);
319 return value; 395 return value;
320 } 396 }
321 397
322 protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 398 [ScriptInvocation]
399 public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path)
323 { 400 {
324 string value = String.Empty; 401 string value = String.Empty;
325 m_store.GetValue(storeID,path,true, out value); 402 m_store.GetValue(storeID,path,true, out value);
@@ -331,80 +408,105 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
331 /// 408 ///
332 /// </summary> 409 /// </summary>
333 // ----------------------------------------------------------------- 410 // -----------------------------------------------------------------
334 protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) 411 [ScriptInvocation]
412 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
335 { 413 {
336 UUID reqID = UUID.Random(); 414 UUID reqID = UUID.Random();
337 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); 415 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); });
338 return reqID; 416 return reqID;
339 } 417 }
340 418
341 protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 419 [ScriptInvocation]
420 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
342 { 421 {
343 UUID reqID = UUID.Random(); 422 UUID reqID = UUID.Random();
344 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); 423 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); });
345 return reqID; 424 return reqID;
346 } 425 }
347 426
348 private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
349 {
350 try
351 {
352 m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
353 return;
354 }
355 catch (Exception e)
356 {
357 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString());
358 }
359
360 DispatchValue(scriptID,reqID,String.Empty);
361 }
362
363
364 // ----------------------------------------------------------------- 427 // -----------------------------------------------------------------
365 /// <summary> 428 /// <summary>
366 /// 429 ///
367 /// </summary> 430 /// </summary>
368 // ----------------------------------------------------------------- 431 // -----------------------------------------------------------------
369 protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) 432 [ScriptInvocation]
433 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
370 { 434 {
371 UUID reqID = UUID.Random(); 435 UUID reqID = UUID.Random();
372 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); 436 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); });
373 return reqID; 437 return reqID;
374 } 438 }
375 439
376 protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 440 [ScriptInvocation]
441 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
377 { 442 {
378 UUID reqID = UUID.Random(); 443 UUID reqID = UUID.Random();
379 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); 444 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); });
380 return reqID; 445 return reqID;
381 } 446 }
382 447
383 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) 448#endregion
449
450 // -----------------------------------------------------------------
451 /// <summary>
452 ///
453 /// </summary>
454 // -----------------------------------------------------------------
455 protected void GenerateRuntimeError(string msg)
456 {
457 m_log.InfoFormat("[JsonStore] runtime error: {0}",msg);
458 throw new Exception("JsonStore Runtime Error: " + msg);
459 }
460
461 // -----------------------------------------------------------------
462 /// <summary>
463 ///
464 /// </summary>
465 // -----------------------------------------------------------------
466 protected void DispatchValue(UUID scriptID, UUID reqID, string value)
467 {
468 m_comms.DispatchReply(scriptID,1,value,reqID.ToString());
469 }
470
471 // -----------------------------------------------------------------
472 /// <summary>
473 ///
474 /// </summary>
475 // -----------------------------------------------------------------
476 private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
384 { 477 {
385 try 478 try
386 { 479 {
387 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); 480 m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
388 return; 481 return;
389 } 482 }
390 catch (Exception e) 483 catch (Exception e)
391 { 484 {
392 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); 485 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
393 } 486 }
394 487
395 DispatchValue(scriptID,reqID,String.Empty); 488 DispatchValue(scriptID,reqID,String.Empty);
396 } 489 }
397 490
398#endregion
399 491
400 // ----------------------------------------------------------------- 492 // -----------------------------------------------------------------
401 /// <summary> 493 /// <summary>
402 /// 494 ///
403 /// </summary> 495 /// </summary>
404 // ----------------------------------------------------------------- 496 // -----------------------------------------------------------------
405 protected void DispatchValue(UUID scriptID, UUID reqID, string value) 497 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
406 { 498 {
407 m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); 499 try
500 {
501 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
502 return;
503 }
504 catch (Exception e)
505 {
506 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
507 }
508
509 DispatchValue(scriptID,reqID,String.Empty);
408 } 510 }
409 511
410 // ----------------------------------------------------------------- 512 // -----------------------------------------------------------------
@@ -412,31 +514,40 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
412 /// 514 ///
413 /// </summary> 515 /// </summary>
414 // ----------------------------------------------------------------- 516 // -----------------------------------------------------------------
415 private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) 517 private void DoJsonReadNotecard(
518 UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
416 { 519 {
520 UUID assetID;
521
522 if (!UUID.TryParse(notecardIdentifier, out assetID))
523 {
524 SceneObjectPart part = m_scene.GetSceneObjectPart(hostID);
525 assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard);
526 }
527
417 AssetBase a = m_scene.AssetService.Get(assetID.ToString()); 528 AssetBase a = m_scene.AssetService.Get(assetID.ToString());
418 if (a == null) 529 if (a == null)
419 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID)); 530 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID));
420 531
421 if (a.Type != (sbyte)AssetType.Notecard) 532 if (a.Type != (sbyte)AssetType.Notecard)
422 GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); 533 GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID));
423 534
424 m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID); 535 m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID);
425 536
426 try 537 try
427 { 538 {
428 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); 539 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
429 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; 540 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
430 m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); 541 m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
431 return; 542 return;
432 } 543 }
433 catch (Exception e) 544 catch (Exception e)
434 { 545 {
435 m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message); 546 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
436 } 547 }
437 548
438 GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); 549 GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID));
439 m_comms.DispatchReply(scriptID,0,"",reqID.ToString()); 550 m_comms.DispatchReply(scriptID, 0, "", reqID.ToString());
440 } 551 }
441 552
442 // ----------------------------------------------------------------- 553 // -----------------------------------------------------------------
@@ -494,5 +605,43 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
494 605
495 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); 606 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString());
496 } 607 }
608
609 // -----------------------------------------------------------------
610 /// <summary>
611 /// Convert a list of values that are path components to a single string path
612 /// </summary>
613 // -----------------------------------------------------------------
614 protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$");
615 private string ConvertList2Path(object[] pathlist)
616 {
617 string path = "";
618 for (int i = 0; i < pathlist.Length; i++)
619 {
620 string token = "";
621
622 if (pathlist[i] is string)
623 {
624 token = pathlist[i].ToString();
625
626 // Check to see if this is a bare number which would not be a valid
627 // identifier otherwise
628 if (m_ArrayPattern.IsMatch(token))
629 token = '[' + token + ']';
630 }
631 else if (pathlist[i] is int)
632 {
633 token = "[" + pathlist[i].ToString() + "]";
634 }
635 else
636 {
637 token = "." + pathlist[i].ToString() + ".";
638 }
639
640 path += token + ".";
641 }
642
643 return path;
644 }
645
497 } 646 }
498} 647}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
new file mode 100644
index 0000000..bfa9937
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -0,0 +1,901 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.Scripting.ScriptModuleComms;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api;
41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
46{
47 /// <summary>
48 /// Tests for inventory functions in LSL
49 /// </summary>
50 [TestFixture]
51 public class JsonStoreScriptModuleTests : OpenSimTestCase
52 {
53 private Scene m_scene;
54 private MockScriptEngine m_engine;
55 private ScriptModuleCommsModule m_smcm;
56 private JsonStoreScriptModule m_jssm;
57
58 [TestFixtureSetUp]
59 public void FixtureInit()
60 {
61 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
62 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
63 }
64
65 [TestFixtureTearDown]
66 public void TearDown()
67 {
68 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
69 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
70 // tests really shouldn't).
71 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
72 }
73
74 [SetUp]
75 public override void SetUp()
76 {
77 base.SetUp();
78
79 IConfigSource configSource = new IniConfigSource();
80 IConfig jsonStoreConfig = configSource.AddConfig("JsonStore");
81 jsonStoreConfig.Set("Enabled", "true");
82
83 m_engine = new MockScriptEngine();
84 m_smcm = new ScriptModuleCommsModule();
85 JsonStoreModule jsm = new JsonStoreModule();
86 m_jssm = new JsonStoreScriptModule();
87
88 m_scene = new SceneHelpers().SetupScene();
89 SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm);
90
91 try
92 {
93 m_smcm.RegisterScriptInvocation(this, "DummyTestMethod");
94 }
95 catch (ArgumentException)
96 {
97 Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier.");
98 }
99
100 // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods.
101 }
102
103 private object InvokeOp(string name, params object[] args)
104 {
105 return InvokeOpOnHost(name, UUID.Zero, args);
106 }
107
108 private object InvokeOpOnHost(string name, UUID hostId, params object[] args)
109 {
110 return m_smcm.InvokeOperation(hostId, UUID.Zero, name, args);
111 }
112
113 [Test]
114 public void TestJsonCreateStore()
115 {
116 TestHelpers.InMethod();
117// TestHelpers.EnableLogging();
118
119 // Test blank store
120 {
121 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
122 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
123 }
124
125 // Test single element store
126 {
127 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
128 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
129 }
130
131 // Test with an integer value
132 {
133 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }");
134 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
135
136 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
137 Assert.That(value, Is.EqualTo("42.15"));
138 }
139
140 // Test with an array as the root node
141 {
142 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]");
143 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
144
145 string value = (string)InvokeOp("JsonGetValue", storeId, "[1]");
146 Assert.That(value, Is.EqualTo("two"));
147 }
148 }
149
150 [Test]
151 public void TestJsonDestroyStore()
152 {
153 TestHelpers.InMethod();
154// TestHelpers.EnableLogging();
155
156 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
157 int dsrv = (int)InvokeOp("JsonDestroyStore", storeId);
158
159 Assert.That(dsrv, Is.EqualTo(1));
160
161 int tprv = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
162 Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
163 }
164
165 [Test]
166 public void TestJsonDestroyStoreNotExists()
167 {
168 TestHelpers.InMethod();
169// TestHelpers.EnableLogging();
170
171 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
172
173 int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId);
174
175 Assert.That(dsrv, Is.EqualTo(0));
176 }
177
178 [Test]
179 public void TestJsonGetValue()
180 {
181 TestHelpers.InMethod();
182// TestHelpers.EnableLogging();
183
184 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }");
185
186 {
187 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello.World");
188 Assert.That(value, Is.EqualTo("Two"));
189 }
190
191 // Test get of path section instead of leaf
192 {
193 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
194 Assert.That(value, Is.EqualTo(""));
195 }
196
197 // Test get of non-existing value
198 {
199 string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo");
200 Assert.That(fakeValueGet, Is.EqualTo(""));
201 }
202
203 // Test get from non-existing store
204 {
205 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
206 string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
207 Assert.That(fakeStoreValueGet, Is.EqualTo(""));
208 }
209 }
210
211 [Test]
212 public void TestJsonGetJson()
213 {
214 TestHelpers.InMethod();
215// TestHelpers.EnableLogging();
216
217 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }");
218
219 {
220 string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World");
221 Assert.That(value, Is.EqualTo("'Two'"));
222 }
223
224 // Test get of path section instead of leaf
225 {
226 string value = (string)InvokeOp("JsonGetJson", storeId, "Hello");
227 Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}"));
228 }
229
230 // Test get of non-existing value
231 {
232 string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo");
233 Assert.That(fakeValueGet, Is.EqualTo(""));
234 }
235
236 // Test get from non-existing store
237 {
238 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
239 string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello");
240 Assert.That(fakeStoreValueGet, Is.EqualTo(""));
241 }
242 }
243
244// [Test]
245// public void TestJsonTakeValue()
246// {
247// TestHelpers.InMethod();
248//// TestHelpers.EnableLogging();
249//
250// UUID storeId
251// = (UUID)m_smcm.InvokeOperation(
252// UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" });
253//
254// string value
255// = (string)m_smcm.InvokeOperation(
256// UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" });
257//
258// Assert.That(value, Is.EqualTo("World"));
259//
260// string value2
261// = (string)m_smcm.InvokeOperation(
262// UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
263//
264// Assert.That(value, Is.Null);
265// }
266
267 [Test]
268 public void TestJsonRemoveValue()
269 {
270 TestHelpers.InMethod();
271// TestHelpers.EnableLogging();
272
273 // Test remove of node in object pointing to a string
274 {
275 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
276
277 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
278 Assert.That(returnValue, Is.EqualTo(1));
279
280 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
281 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
282
283 string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello");
284 Assert.That(returnValue2, Is.EqualTo(""));
285 }
286
287 // Test remove of node in object pointing to another object
288 {
289 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }");
290
291 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
292 Assert.That(returnValue, Is.EqualTo(1));
293
294 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
295 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
296
297 string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello");
298 Assert.That(returnValue2, Is.EqualTo(""));
299 }
300
301 // Test remove of node in an array
302 {
303 UUID storeId
304 = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }");
305
306 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]");
307 Assert.That(returnValue, Is.EqualTo(1));
308
309 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[0]");
310 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
311
312 result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[1]");
313 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
314
315 string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]");
316 Assert.That(stringReturnValue, Is.EqualTo("value2"));
317
318 stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]");
319 Assert.That(stringReturnValue, Is.EqualTo(""));
320 }
321
322 // Test remove of non-existing value
323 {
324 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
325
326 int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese");
327 Assert.That(fakeValueRemove, Is.EqualTo(0));
328 }
329
330 {
331 // Test get from non-existing store
332 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
333 int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello");
334 Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
335 }
336 }
337
338// [Test]
339// public void TestJsonTestPath()
340// {
341// TestHelpers.InMethod();
342//// TestHelpers.EnableLogging();
343//
344// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
345//
346// {
347// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World");
348// Assert.That(result, Is.EqualTo(1));
349// }
350//
351// // Test for path which does not resolve to a value.
352// {
353// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
354// Assert.That(result, Is.EqualTo(0));
355// }
356//
357// {
358// int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo");
359// Assert.That(result2, Is.EqualTo(0));
360// }
361//
362// // Test with fake store
363// {
364// UUID fakeStoreId = TestHelpers.ParseTail(0x500);
365// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello");
366// Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
367// }
368// }
369
370// [Test]
371// public void TestJsonTestPathJson()
372// {
373// TestHelpers.InMethod();
374//// TestHelpers.EnableLogging();
375//
376// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
377//
378// {
379// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World");
380// Assert.That(result, Is.EqualTo(1));
381// }
382//
383// // Test for path which does not resolve to a value.
384// {
385// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello");
386// Assert.That(result, Is.EqualTo(1));
387// }
388//
389// {
390// int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo");
391// Assert.That(result2, Is.EqualTo(0));
392// }
393//
394// // Test with fake store
395// {
396// UUID fakeStoreId = TestHelpers.ParseTail(0x500);
397// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello");
398// Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
399// }
400// }
401
402 [Test]
403 public void TestJsonGetArrayLength()
404 {
405 TestHelpers.InMethod();
406// TestHelpers.EnableLogging();
407
408 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
409
410 {
411 int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World");
412 Assert.That(result, Is.EqualTo(2));
413 }
414
415 // Test path which is not an array
416 {
417 int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello");
418 Assert.That(result, Is.EqualTo(-1));
419 }
420
421 // Test fake path
422 {
423 int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo");
424 Assert.That(result, Is.EqualTo(-1));
425 }
426
427 // Test fake store
428 {
429 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
430 int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World");
431 Assert.That(result, Is.EqualTo(-1));
432 }
433 }
434
435 [Test]
436 public void TestJsonGetNodeType()
437 {
438 TestHelpers.InMethod();
439// TestHelpers.EnableLogging();
440
441 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
442
443 {
444 int result = (int)InvokeOp("JsonGetNodeType", storeId, ".");
445 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT));
446 }
447
448 {
449 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
450 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT));
451 }
452
453 {
454 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World");
455 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_ARRAY));
456 }
457
458 {
459 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[0]");
460 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
461 }
462
463 {
464 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[1]");
465 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
466 }
467
468 // Test for non-existant path
469 {
470 int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo");
471 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
472 }
473
474 // Test for non-existant store
475 {
476 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
477 int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, ".");
478 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
479 }
480 }
481
482 [Test]
483 public void TestJsonList2Path()
484 {
485 TestHelpers.InMethod();
486// TestHelpers.EnableLogging();
487
488 // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason
489 // - some confusion with the methods that take a params object[] invocation.
490 {
491 string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" });
492 Assert.That(result, Is.EqualTo("{foo}"));
493 }
494
495 {
496 string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" });
497 Assert.That(result, Is.EqualTo("{foo}.{bar}"));
498 }
499
500 {
501 string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" });
502 Assert.That(result, Is.EqualTo("{foo}.[1].{bar}"));
503 }
504 }
505
506 [Test]
507 public void TestJsonSetValue()
508 {
509 TestHelpers.InMethod();
510// TestHelpers.EnableLogging();
511
512 {
513 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
514
515 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times");
516 Assert.That(result, Is.EqualTo(1));
517
518 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
519 Assert.That(value, Is.EqualTo("Times"));
520 }
521
522 // Test setting a key containing periods with delineation
523 {
524 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
525
526 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times");
527 Assert.That(result, Is.EqualTo(1));
528
529 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}");
530 Assert.That(value, Is.EqualTo("Times"));
531 }
532
533 // *** Test [] ***
534
535 // Test setting a key containing unbalanced ] without delineation. Expecting failure
536 {
537 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
538
539 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times");
540 Assert.That(result, Is.EqualTo(0));
541
542 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus");
543 Assert.That(value, Is.EqualTo(""));
544 }
545
546 // Test setting a key containing unbalanced [ without delineation. Expecting failure
547 {
548 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
549
550 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times");
551 Assert.That(result, Is.EqualTo(0));
552
553 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus");
554 Assert.That(value, Is.EqualTo(""));
555 }
556
557 // Test setting a key containing unbalanced [] without delineation. Expecting failure
558 {
559 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
560
561 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times");
562 Assert.That(result, Is.EqualTo(0));
563
564 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus");
565 Assert.That(value, Is.EqualTo(""));
566 }
567
568 // Test setting a key containing unbalanced ] with delineation
569 {
570 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
571
572 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times");
573 Assert.That(result, Is.EqualTo(1));
574
575 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}");
576 Assert.That(value, Is.EqualTo("Times"));
577 }
578
579 // Test setting a key containing unbalanced [ with delineation
580 {
581 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
582
583 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times");
584 Assert.That(result, Is.EqualTo(1));
585
586 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}");
587 Assert.That(value, Is.EqualTo("Times"));
588 }
589
590 // Test setting a key containing empty balanced [] with delineation
591 {
592 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
593
594 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times");
595 Assert.That(result, Is.EqualTo(1));
596
597 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}");
598 Assert.That(value, Is.EqualTo("Times"));
599 }
600
601// // Commented out as this currently unexpectedly fails.
602// // Test setting a key containing brackets around an integer with delineation
603// {
604// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
605//
606// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times");
607// Assert.That(result, Is.EqualTo(1));
608//
609// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}");
610// Assert.That(value, Is.EqualTo("Times"));
611// }
612
613 // *** Test {} ***
614
615 // Test setting a key containing unbalanced } without delineation. Expecting failure (?)
616 {
617 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
618
619 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times");
620 Assert.That(result, Is.EqualTo(0));
621
622 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
623 Assert.That(value, Is.EqualTo(""));
624 }
625
626 // Test setting a key containing unbalanced { without delineation. Expecting failure (?)
627 {
628 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
629
630 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times");
631 Assert.That(result, Is.EqualTo(0));
632
633 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
634 Assert.That(value, Is.EqualTo(""));
635 }
636
637// // Commented out as this currently unexpectedly fails.
638// // Test setting a key containing unbalanced }
639// {
640// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
641//
642// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times");
643// Assert.That(result, Is.EqualTo(0));
644// }
645
646 // Test setting a key containing unbalanced { with delineation
647 {
648 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
649
650 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times");
651 Assert.That(result, Is.EqualTo(1));
652
653 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}");
654 Assert.That(value, Is.EqualTo("Times"));
655 }
656
657 // Test setting a key containing balanced {} with delineation. This should fail.
658 {
659 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
660
661 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times");
662 Assert.That(result, Is.EqualTo(0));
663
664 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}");
665 Assert.That(value, Is.EqualTo(""));
666 }
667
668 // Test setting to location that does not exist. This should fail.
669 {
670 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
671
672 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times");
673 Assert.That(result, Is.EqualTo(0));
674
675 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
676 Assert.That(value, Is.EqualTo(""));
677 }
678
679 // Test with fake store
680 {
681 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
682 int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World");
683 Assert.That(fakeStoreValueSet, Is.EqualTo(0));
684 }
685 }
686
687 [Test]
688 public void TestJsonSetJson()
689 {
690 TestHelpers.InMethod();
691// TestHelpers.EnableLogging();
692
693 // Single quoted token case
694 {
695 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
696
697 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'");
698 Assert.That(result, Is.EqualTo(1));
699
700 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
701 Assert.That(value, Is.EqualTo("Times"));
702 }
703
704 // Sub-tree case
705 {
706 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
707
708 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }");
709 Assert.That(result, Is.EqualTo(1));
710
711 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled");
712 Assert.That(value, Is.EqualTo("Times"));
713 }
714
715 // If setting single strings in JsonSetValueJson, these must be single quoted tokens, not bare strings.
716 {
717 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
718
719 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times");
720 Assert.That(result, Is.EqualTo(0));
721
722 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
723 Assert.That(value, Is.EqualTo(""));
724 }
725
726 // Test setting to location that does not exist. This should fail.
727 {
728 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
729
730 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'");
731 Assert.That(result, Is.EqualTo(0));
732
733 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
734 Assert.That(value, Is.EqualTo(""));
735 }
736
737 // Test with fake store
738 {
739 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
740 int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'");
741 Assert.That(fakeStoreValueSet, Is.EqualTo(0));
742 }
743 }
744
745 /// <summary>
746 /// Test for writing json to a notecard
747 /// </summary>
748 /// <remarks>
749 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
750 /// it via the MockScriptEngine or perhaps by a dummy script instance.
751 /// </remarks>
752 [Test]
753 public void TestJsonWriteNotecard()
754 {
755 TestHelpers.InMethod();
756// TestHelpers.EnableLogging();
757
758 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
759 m_scene.AddSceneObject(so);
760
761 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
762
763 {
764 string notecardName = "nc1";
765
766 // Write notecard
767 UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName);
768 Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
769
770 TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName);
771 Assert.That(nc1Item, Is.Not.Null);
772
773 // TODO: Should independently check the contents.
774 }
775
776 // TODO: Write partial test
777
778 {
779 // Try to write notecard for a bad path
780 // In this case we do get a request id but no notecard is written.
781 string badPathNotecardName = "badPathNotecardName";
782
783 UUID writeNotecardBadPathRequestId
784 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "flibble", badPathNotecardName);
785 Assert.That(writeNotecardBadPathRequestId, Is.Not.EqualTo(UUID.Zero));
786
787 TaskInventoryItem badPathItem = so.RootPart.Inventory.GetInventoryItem(badPathNotecardName);
788 Assert.That(badPathItem, Is.Null);
789 }
790
791 {
792 // Test with fake store
793 // In this case we do get a request id but no notecard is written.
794 string fakeStoreNotecardName = "fakeStoreNotecardName";
795
796 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
797 UUID fakeStoreWriteNotecardValue
798 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName);
799 Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero));
800
801 TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName);
802 Assert.That(fakeStoreItem, Is.Null);
803 }
804 }
805
806 /// <summary>
807 /// Test for reading json from a notecard
808 /// </summary>
809 /// <remarks>
810 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
811 /// it via the MockScriptEngine or perhaps by a dummy script instance.
812 /// </remarks>
813 [Test]
814 public void TestJsonReadNotecard()
815 {
816 TestHelpers.InMethod();
817// TestHelpers.EnableLogging();
818
819 string notecardName = "nc1";
820
821 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
822 m_scene.AddSceneObject(so);
823
824 UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
825
826 // Write notecard
827 InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName);
828
829 {
830 // Read notecard
831 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
832 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName);
833 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
834
835 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
836 Assert.That(value, Is.EqualTo("World"));
837 }
838
839 {
840 // Read notecard to new single component path
841 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
842 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName);
843 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
844
845 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
846 Assert.That(value, Is.EqualTo(""));
847
848 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello");
849 Assert.That(value, Is.EqualTo("World"));
850 }
851
852 {
853 // Read notecard to new multi-component path. This should not work.
854 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
855 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
856 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
857
858 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
859 Assert.That(value, Is.EqualTo(""));
860
861 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
862 Assert.That(value, Is.EqualTo(""));
863 }
864
865 {
866 // Read notecard to existing multi-component path. This should work
867 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
868 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
869 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
870
871 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
872 Assert.That(value, Is.EqualTo(""));
873
874 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
875 Assert.That(value, Is.EqualTo("World"));
876 }
877
878 {
879 // Read notecard to invalid path. This should not work.
880 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
881 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName);
882 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
883
884 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
885 Assert.That(value, Is.EqualTo(""));
886 }
887
888 {
889 // Try read notecard to fake store.
890 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
891 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName);
892 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
893
894 string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
895 Assert.That(value, Is.EqualTo(""));
896 }
897 }
898
899 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
900 }
901} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
index 6120a81..709d389 100644
--- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
@@ -46,6 +46,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
46{ 46{
47 public class XmlRpcInfo 47 public class XmlRpcInfo
48 { 48 {
49 public UUID item;
49 public UUID channel; 50 public UUID channel;
50 public string uri; 51 public string uri;
51 } 52 }
@@ -88,6 +89,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
88 return; 89 return;
89 90
90 scene.RegisterModuleInterface<IXmlRpcRouter>(this); 91 scene.RegisterModuleInterface<IXmlRpcRouter>(this);
92
93 IScriptModule scriptEngine = scene.RequestModuleInterface<IScriptModule>();
94 if ( scriptEngine != null )
95 {
96 scriptEngine.OnScriptRemoved += this.ScriptRemoved;
97 scriptEngine.OnObjectRemoved += this.ObjectRemoved;
98
99 }
91 } 100 }
92 101
93 public void RegionLoaded(Scene scene) 102 public void RegionLoaded(Scene scene)
@@ -120,22 +129,36 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
120 129
121 public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) 130 public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri)
122 { 131 {
123 if (!m_Channels.ContainsKey(itemID)) 132 if (!m_Enabled)
124 { 133 return;
125 XmlRpcInfo info = new XmlRpcInfo();
126 info.channel = channel;
127 info.uri = uri;
128 134
129 bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>( 135 m_log.InfoFormat("[XMLRPC GRID ROUTER]: New receiver Obj: {0} Ch: {1} ID: {2} URI: {3}",
130 "POST", m_ServerURI+"/RegisterChannel/", info); 136 objectID.ToString(), channel.ToString(), itemID.ToString(), uri);
131 137
132 if (!success) 138 XmlRpcInfo info = new XmlRpcInfo();
133 { 139 info.channel = channel;
134 m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); 140 info.uri = uri;
135 } 141 info.item = itemID;
142
143 bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>(
144 "POST", m_ServerURI+"/RegisterChannel/", info);
136 145
137 m_Channels[itemID] = channel; 146 if (!success)
147 {
148 m_log.Error("[XMLRPC GRID ROUTER] Error contacting server");
138 } 149 }
150
151 m_Channels[itemID] = channel;
152
153 }
154
155 public void UnRegisterReceiver(string channelID, UUID itemID)
156 {
157 if (!m_Enabled)
158 return;
159
160 RemoveChannel(itemID);
161
139 } 162 }
140 163
141 public void ScriptRemoved(UUID itemID) 164 public void ScriptRemoved(UUID itemID)
@@ -143,10 +166,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
143 if (!m_Enabled) 166 if (!m_Enabled)
144 return; 167 return;
145 168
146 if (m_Channels.ContainsKey(itemID)) 169 RemoveChannel(itemID);
170
171 }
172
173 public void ObjectRemoved(UUID objectID)
174 {
175 // m_log.InfoFormat("[XMLRPC GRID ROUTER]: Object Removed {0}",objectID.ToString());
176 }
177
178 private bool RemoveChannel(UUID itemID)
179 {
180 if(!m_Channels.ContainsKey(itemID))
181 {
182 m_log.InfoFormat("[XMLRPC GRID ROUTER]: Attempted to unregister non-existing Item: {0}", itemID.ToString());
183 return false;
184 }
185
186 XmlRpcInfo info = new XmlRpcInfo();
187
188 info.channel = m_Channels[itemID];
189 info.item = itemID;
190 info.uri = "http://0.0.0.0:00";
191
192 if (info != null)
147 { 193 {
148 bool success = SynchronousRestObjectRequester.MakeRequest<UUID, bool>( 194 bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>(
149 "POST", m_ServerURI+"/RemoveChannel/", m_Channels[itemID]); 195 "POST", m_ServerURI+"/RemoveChannel/", info);
150 196
151 if (!success) 197 if (!success)
152 { 198 {
@@ -154,11 +200,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
154 } 200 }
155 201
156 m_Channels.Remove(itemID); 202 m_Channels.Remove(itemID);
203 return true;
157 } 204 }
158 } 205 return false;
159
160 public void ObjectRemoved(UUID objectID)
161 {
162 } 206 }
163 } 207 }
164} 208}
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs
index 4bde52a..32549d6 100644
--- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs
@@ -104,12 +104,18 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule
104 } 104 }
105 } 105 }
106 106
107 public void UnRegisterReceiver(string channelID, UUID itemID)
108 {
109 }
110
107 public void ScriptRemoved(UUID itemID) 111 public void ScriptRemoved(UUID itemID)
108 { 112 {
113 // System.Console.WriteLine("TEST Script Removed!");
109 } 114 }
110 115
111 public void ObjectRemoved(UUID objectID) 116 public void ObjectRemoved(UUID objectID)
112 { 117 {
118 // System.Console.WriteLine("TEST Obj Removed!");
113 } 119 }
114 } 120 }
115} 121}