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.cs368
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs147
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs301
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs800
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs82
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs6
7 files changed, 1712 insertions, 163 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..ca3989a 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,25 +68,106 @@ 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 PathType(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 ///
@@ -94,13 +175,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
94 // ----------------------------------------------------------------- 175 // -----------------------------------------------------------------
95 public bool TestPath(string expr, bool useJson) 176 public bool TestPath(string expr, bool useJson)
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 false;
181
182 OSD result = ProcessPathExpression(ValueStore,path);
99 183
100 if (result == null) 184 if (result == null)
101 return false; 185 return false;
102 186
103 if (useJson || result.Type == OSDType.String) 187 if (useJson || OSDBaseType(result.Type))
104 return true; 188 return true;
105 189
106 return false; 190 return false;
@@ -111,10 +195,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
111 /// 195 ///
112 /// </summary> 196 /// </summary>
113 // ----------------------------------------------------------------- 197 // -----------------------------------------------------------------
198 public int ArrayLength(string expr)
199 {
200 Stack<string> path;
201 if (! ParsePathExpression(expr,out path))
202 return -1;
203
204 OSD result = ProcessPathExpression(ValueStore,path);
205 if (result != null && result.Type == OSDType.Array)
206 {
207 OSDArray arr = result as OSDArray;
208 return arr.Count;
209 }
210
211 return -1;
212 }
213
214 // -----------------------------------------------------------------
215 /// <summary>
216 ///
217 /// </summary>
218 // -----------------------------------------------------------------
114 public bool GetValue(string expr, out string value, bool useJson) 219 public bool GetValue(string expr, out string value, bool useJson)
115 { 220 {
116 Stack<string> path = ParsePathExpression(expr); 221 Stack<string> path;
117 OSD result = ProcessPathExpression(m_ValueStore,path); 222 if (! ParsePathExpression(expr,out path))
223 {
224 value = "";
225 return false;
226 }
227
228 OSD result = ProcessPathExpression(ValueStore,path);
118 return ConvertOutputValue(result,out value,useJson); 229 return ConvertOutputValue(result,out value,useJson);
119 } 230 }
120 231
@@ -136,7 +247,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
136 // ----------------------------------------------------------------- 247 // -----------------------------------------------------------------
137 public bool SetValue(string expr, string value, bool useJson) 248 public bool SetValue(string expr, string value, bool useJson)
138 { 249 {
139 OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value); 250 OSD ovalue;
251
252 // One note of caution... if you use an empty string in the
253 // structure it will be assumed to be a default value and will
254 // not be seialized in the json
255
256 if (useJson)
257 {
258 // There doesn't appear to be a good way to determine if the
259 // value is valid Json other than to let the parser crash
260 try
261 {
262 ovalue = OSDParser.DeserializeJson(value);
263 }
264 catch (Exception e)
265 {
266 if (value.StartsWith("'") && value.EndsWith("'"))
267 {
268 ovalue = new OSDString(value.Substring(1,value.Length - 2));
269 }
270 else
271 {
272 return false;
273 }
274 }
275 }
276 else
277 {
278 ovalue = new OSDString(value);
279 }
280
140 return SetValueFromExpression(expr,ovalue); 281 return SetValueFromExpression(expr,ovalue);
141 } 282 }
142 283
@@ -147,10 +288,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
147 // ----------------------------------------------------------------- 288 // -----------------------------------------------------------------
148 public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) 289 public bool TakeValue(string expr, bool useJson, TakeValueCallback cback)
149 { 290 {
150 Stack<string> path = ParsePathExpression(expr); 291 Stack<string> path;
292 if (! ParsePathExpression(expr,out path))
293 return false;
294
151 string pexpr = PathExpressionToKey(path); 295 string pexpr = PathExpressionToKey(path);
152 296
153 OSD result = ProcessPathExpression(m_ValueStore,path); 297 OSD result = ProcessPathExpression(ValueStore,path);
154 if (result == null) 298 if (result == null)
155 { 299 {
156 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); 300 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
@@ -178,10 +322,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
178 // ----------------------------------------------------------------- 322 // -----------------------------------------------------------------
179 public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) 323 public bool ReadValue(string expr, bool useJson, TakeValueCallback cback)
180 { 324 {
181 Stack<string> path = ParsePathExpression(expr); 325 Stack<string> path;
326 if (! ParsePathExpression(expr,out path))
327 return false;
328
182 string pexpr = PathExpressionToKey(path); 329 string pexpr = PathExpressionToKey(path);
183 330
184 OSD result = ProcessPathExpression(m_ValueStore,path); 331 OSD result = ProcessPathExpression(ValueStore,path);
185 if (result == null) 332 if (result == null)
186 { 333 {
187 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); 334 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
@@ -208,25 +355,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
208 // ----------------------------------------------------------------- 355 // -----------------------------------------------------------------
209 protected bool SetValueFromExpression(string expr, OSD ovalue) 356 protected bool SetValueFromExpression(string expr, OSD ovalue)
210 { 357 {
211 Stack<string> path = ParsePathExpression(expr); 358 Stack<string> path;
359 if (! ParsePathExpression(expr,out path))
360 return false;
361
212 if (path.Count == 0) 362 if (path.Count == 0)
213 { 363 {
214 m_ValueStore = ovalue; 364 ValueStore = ovalue;
365 StringSpace = 0;
215 return true; 366 return true;
216 } 367 }
217 368
369 // pkey will be the final element in the path, we pull it out here to make sure
370 // that the assignment works correctly
218 string pkey = path.Pop(); 371 string pkey = path.Pop();
219 string pexpr = PathExpressionToKey(path); 372 string pexpr = PathExpressionToKey(path);
220 if (pexpr != "") 373 if (pexpr != "")
221 pexpr += "."; 374 pexpr += ".";
222 375
223 OSD result = ProcessPathExpression(m_ValueStore,path); 376 OSD result = ProcessPathExpression(ValueStore,path);
224 if (result == null) 377 if (result == null)
225 return false; 378 return false;
226 379
227 Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]"); 380 // Check pkey, the last element in the path, for and extract array references
228 MatchCollection amatches = aPattern.Matches(pkey,0); 381 MatchCollection amatches = m_ArrayPattern.Matches(pkey,0);
229
230 if (amatches.Count > 0) 382 if (amatches.Count > 0)
231 { 383 {
232 if (result.Type != OSDType.Array) 384 if (result.Type != OSDType.Array)
@@ -242,8 +394,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
242 { 394 {
243 string npkey = String.Format("[{0}]",amap.Count); 395 string npkey = String.Format("[{0}]",amap.Count);
244 396
245 amap.Add(ovalue); 397 if (ovalue != null)
246 InvokeNextCallback(pexpr + npkey); 398 {
399 StringSpace += ComputeSizeOf(ovalue);
400
401 amap.Add(ovalue);
402 InvokeNextCallback(pexpr + npkey);
403 }
247 return true; 404 return true;
248 } 405 }
249 406
@@ -251,9 +408,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
251 if (0 <= aval && aval < amap.Count) 408 if (0 <= aval && aval < amap.Count)
252 { 409 {
253 if (ovalue == null) 410 if (ovalue == null)
411 {
412 StringSpace -= ComputeSizeOf(amap[aval]);
254 amap.RemoveAt(aval); 413 amap.RemoveAt(aval);
414 }
255 else 415 else
256 { 416 {
417 StringSpace -= ComputeSizeOf(amap[aval]);
418 StringSpace += ComputeSizeOf(ovalue);
257 amap[aval] = ovalue; 419 amap[aval] = ovalue;
258 InvokeNextCallback(pexpr + pkey); 420 InvokeNextCallback(pexpr + pkey);
259 } 421 }
@@ -263,9 +425,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
263 return false; 425 return false;
264 } 426 }
265 427
266 Regex hPattern = new Regex("{([^}]+)}"); 428 // Check for and extract hash references
267 MatchCollection hmatches = hPattern.Matches(pkey,0); 429 MatchCollection hmatches = m_HashPattern.Matches(pkey,0);
268
269 if (hmatches.Count > 0) 430 if (hmatches.Count > 0)
270 { 431 {
271 Match match = hmatches[0]; 432 Match match = hmatches[0];
@@ -274,16 +435,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
274 435
275 if (result is OSDMap) 436 if (result is OSDMap)
276 { 437 {
438 // this is the assignment case
277 OSDMap hmap = result as OSDMap; 439 OSDMap hmap = result as OSDMap;
278 if (ovalue != null) 440 if (ovalue != null)
279 { 441 {
442 StringSpace -= ComputeSizeOf(hmap[hkey]);
443 StringSpace += ComputeSizeOf(ovalue);
444
280 hmap[hkey] = ovalue; 445 hmap[hkey] = ovalue;
281 InvokeNextCallback(pexpr + pkey); 446 InvokeNextCallback(pexpr + pkey);
447 return true;
282 } 448 }
283 else if (hmap.ContainsKey(hkey)) 449
450 // this is the remove case
451 if (hmap.ContainsKey(hkey))
452 {
453 StringSpace -= ComputeSizeOf(hmap[hkey]);
284 hmap.Remove(hkey); 454 hmap.Remove(hkey);
285 455 return true;
286 return true; 456 }
457
458 return false;
287 } 459 }
288 460
289 return false; 461 return false;
@@ -332,39 +504,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
332 /// use a stack because we process the path in inverse order later 504 /// use a stack because we process the path in inverse order later
333 /// </summary> 505 /// </summary>
334 // ----------------------------------------------------------------- 506 // -----------------------------------------------------------------
335 protected static Stack<string> ParsePathExpression(string path) 507 protected static bool ParsePathExpression(string expr, out Stack<string> path)
336 { 508 {
337 Stack<string> m_path = new Stack<string>(); 509 path = new Stack<string>();
338 510
339 // add front and rear separators 511 // add front and rear separators
340 path = "." + path + "."; 512 expr = "." + expr + ".";
341 513
342 // add separators for quoted paths 514 // add separators for quoted exprs and array references
343 Regex pass1 = new Regex("{[^}]+}"); 515 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 516
350 // add quotes to bare identifier 517 // add quotes to bare identifier
351 Regex pass3 = new Regex("\\.([a-zA-Z]+)"); 518 expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0);
352 path = pass3.Replace(path,".{$1}",-1,0);
353 519
354 // remove extra separators 520 // remove extra separators
355 Regex pass4 = new Regex("\\.+"); 521 expr = m_ParsePassFour.Replace(expr,".",-1,0);
356 path = pass4.Replace(path,".",-1,0);
357 522
358 Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); 523 // validate the results (catches extra quote characters for example)
359 if (validate.IsMatch(path)) 524 if (m_ValidatePath.IsMatch(expr))
360 { 525 {
361 Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); 526 MatchCollection matches = m_PathComponent.Matches(expr,0);
362 MatchCollection matches = parser.Matches(path,0);
363 foreach (Match match in matches) 527 foreach (Match match in matches)
364 m_path.Push(match.Groups[1].Value); 528 path.Push(match.Groups[1].Value);
529
530 return true;
365 } 531 }
366 532
367 return m_path; 533 return false;
368 } 534 }
369 535
370 // ----------------------------------------------------------------- 536 // -----------------------------------------------------------------
@@ -385,9 +551,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
385 return null; 551 return null;
386 552
387 // ---------- Check for an array index ---------- 553 // ---------- Check for an array index ----------
388 Regex aPattern = new Regex("\\[([0-9]+)\\]"); 554 MatchCollection amatches = m_SimpleArrayPattern.Matches(pkey,0);
389 MatchCollection amatches = aPattern.Matches(pkey,0); 555
390
391 if (amatches.Count > 0) 556 if (amatches.Count > 0)
392 { 557 {
393 if (rmap.Type != OSDType.Array) 558 if (rmap.Type != OSDType.Array)
@@ -410,9 +575,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
410 } 575 }
411 576
412 // ---------- Check for a hash index ---------- 577 // ---------- Check for a hash index ----------
413 Regex hPattern = new Regex("{([^}]+)}"); 578 MatchCollection hmatches = m_HashPattern.Matches(pkey,0);
414 MatchCollection hmatches = hPattern.Matches(pkey,0); 579
415
416 if (hmatches.Count > 0) 580 if (hmatches.Count > 0)
417 { 581 {
418 if (rmap.Type != OSDType.Map) 582 if (rmap.Type != OSDType.Map)
@@ -456,14 +620,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
456 // The path pointed to an intermediate hash structure 620 // The path pointed to an intermediate hash structure
457 if (result.Type == OSDType.Map) 621 if (result.Type == OSDType.Map)
458 { 622 {
459 value = OSDParser.SerializeJsonString(result as OSDMap); 623 value = OSDParser.SerializeJsonString(result as OSDMap,true);
460 return true; 624 return true;
461 } 625 }
462 626
463 // The path pointed to an intermediate hash structure 627 // The path pointed to an intermediate hash structure
464 if (result.Type == OSDType.Array) 628 if (result.Type == OSDType.Array)
465 { 629 {
466 value = OSDParser.SerializeJsonString(result as OSDArray); 630 value = OSDParser.SerializeJsonString(result as OSDArray,true);
467 return true; 631 return true;
468 } 632 }
469 633
@@ -471,7 +635,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
471 return true; 635 return true;
472 } 636 }
473 637
474 if (result.Type == OSDType.String) 638 if (OSDBaseType(result.Type))
475 { 639 {
476 value = result.AsString(); 640 value = result.AsString();
477 return true; 641 return true;
@@ -496,5 +660,91 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
496 660
497 return pkey; 661 return pkey;
498 } 662 }
663
664 // -----------------------------------------------------------------
665 /// <summary>
666 ///
667 /// </summary>
668 // -----------------------------------------------------------------
669 protected static bool OSDBaseType(OSDType type)
670 {
671 // Should be the list of base types for which AsString() returns
672 // something useful
673 if (type == OSDType.Boolean)
674 return true;
675 if (type == OSDType.Integer)
676 return true;
677 if (type == OSDType.Real)
678 return true;
679 if (type == OSDType.String)
680 return true;
681 if (type == OSDType.UUID)
682 return true;
683 if (type == OSDType.Date)
684 return true;
685 if (type == OSDType.URI)
686 return true;
687
688 return false;
689 }
690
691 // -----------------------------------------------------------------
692 /// <summary>
693 ///
694 /// </summary>
695 // -----------------------------------------------------------------
696 protected static int ComputeSizeOf(OSD value)
697 {
698 string sval;
699
700 if (ConvertOutputValue(value,out sval,true))
701 return sval.Length;
702
703 return 0;
704 }
705 }
706
707 // -----------------------------------------------------------------
708 /// <summary>
709 /// </summary>
710 // -----------------------------------------------------------------
711 public class JsonObjectStore : JsonStore
712 {
713 private static readonly ILog m_log =
714 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
715
716 private Scene m_scene;
717 private UUID m_objectID;
718
719 protected override OSD ValueStore
720 {
721 get
722 {
723 SceneObjectPart sop = m_scene.GetSceneObjectPart(m_objectID);
724 if (sop == null)
725 {
726 // This is bad
727 return null;
728 }
729
730 return sop.DynAttrs.TopLevelMap;
731 }
732
733 // cannot set the top level
734 set
735 {
736 m_log.InfoFormat("[JsonStore] cannot set top level value in object store");
737 }
738 }
739
740 public JsonObjectStore(Scene scene, UUID oid) : base()
741 {
742 m_scene = scene;
743 m_objectID = oid;
744
745 // the size limit is imposed on whatever is already in the store
746 StringSpace = ComputeSizeOf(ValueStore);
747 }
499 } 748 }
749
500} 750}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index e68764a..eec86ef 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,6 +257,51 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
221 /// 257 ///
222 /// </summary> 258 /// </summary>
223 // ----------------------------------------------------------------- 259 // -----------------------------------------------------------------
260 public bool TestStore(UUID storeID)
261 {
262 if (! m_enabled) return false;
263
264 lock (m_JsonValueStore)
265 return m_JsonValueStore.ContainsKey(storeID);
266 }
267
268 // -----------------------------------------------------------------
269 /// <summary>
270 ///
271 /// </summary>
272 // -----------------------------------------------------------------
273 public JsonStoreNodeType PathType(UUID storeID, string path)
274 {
275 if (! m_enabled) return JsonStoreNodeType.Undefined;
276
277 JsonStore map = null;
278 lock (m_JsonValueStore)
279 {
280 if (! m_JsonValueStore.TryGetValue(storeID,out map))
281 {
282 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
283 return JsonStoreNodeType.Undefined;
284 }
285 }
286
287 try
288 {
289 lock (map)
290 return map.PathType(path);
291 }
292 catch (Exception e)
293 {
294 m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
295 }
296
297 return JsonStoreNodeType.Undefined;
298 }
299
300 // -----------------------------------------------------------------
301 /// <summary>
302 ///
303 /// </summary>
304 // -----------------------------------------------------------------
224 public bool TestPath(UUID storeID, string path, bool useJson) 305 public bool TestPath(UUID storeID, string path, bool useJson)
225 { 306 {
226 if (! m_enabled) return false; 307 if (! m_enabled) return false;
@@ -242,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
242 } 323 }
243 catch (Exception e) 324 catch (Exception e)
244 { 325 {
245 m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message); 326 m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
246 } 327 }
247 328
248 return false; 329 return false;
@@ -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 ArrayLength(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..3955bff 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -39,6 +39,7 @@ 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;
44 45
@@ -92,12 +93,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
92 } 93 }
93 catch (Exception e) 94 catch (Exception e)
94 { 95 {
95 m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message); 96 m_log.ErrorFormat("[JsonStoreScripts]: initialization error: {0}", e.Message);
96 return; 97 return;
97 } 98 }
98 99
99 if (m_enabled) 100 if (m_enabled)
100 m_log.DebugFormat("[JsonStoreScripts] module is enabled"); 101 m_log.DebugFormat("[JsonStoreScripts]: module is enabled");
101 } 102 }
102 103
103 // ----------------------------------------------------------------- 104 // -----------------------------------------------------------------
@@ -150,7 +151,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
150 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>(); 151 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>();
151 if (m_comms == null) 152 if (m_comms == null)
152 { 153 {
153 m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined"); 154 m_log.ErrorFormat("[JsonStoreScripts]: ScriptModuleComms interface not defined");
154 m_enabled = false; 155 m_enabled = false;
155 return; 156 return;
156 } 157 }
@@ -158,40 +159,46 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
158 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>(); 159 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>();
159 if (m_store == null) 160 if (m_store == null)
160 { 161 {
161 m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined"); 162 m_log.ErrorFormat("[JsonStoreScripts]: JsonModule interface not defined");
162 m_enabled = false; 163 m_enabled = false;
163 return; 164 return;
164 } 165 }
165 166
166 try 167 try
167 { 168 {
168 m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); 169 m_comms.RegisterScriptInvocations(this);
169 m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); 170 m_comms.RegisterConstants(this);
171
172 // m_comms.RegisterScriptInvocation(this, "JsonCreateStore");
173 // m_comms.RegisterScriptInvocation(this, "JsonAttachObjectStore");
174 // m_comms.RegisterScriptInvocation(this, "JsonDestroyStore");
175 // m_comms.RegisterScriptInvocation(this, "JsonTestStore");
170 176
171 m_comms.RegisterScriptInvocation(this,"JsonReadNotecard"); 177 // m_comms.RegisterScriptInvocation(this, "JsonReadNotecard");
172 m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); 178 // m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard");
173 179
174 m_comms.RegisterScriptInvocation(this,"JsonTestPath"); 180 // m_comms.RegisterScriptInvocation(this, "JsonTestPathList");
175 m_comms.RegisterScriptInvocation(this,"JsonTestPathJson"); 181 // m_comms.RegisterScriptInvocation(this, "JsonTestPath");
182 // m_comms.RegisterScriptInvocation(this, "JsonTestPathJson");
176 183
177 m_comms.RegisterScriptInvocation(this,"JsonGetValue"); 184 // m_comms.RegisterScriptInvocation(this, "JsonGetValue");
178 m_comms.RegisterScriptInvocation(this,"JsonGetValueJson"); 185 // m_comms.RegisterScriptInvocation(this, "JsonGetValueJson");
179 186
180 m_comms.RegisterScriptInvocation(this,"JsonTakeValue"); 187 // m_comms.RegisterScriptInvocation(this, "JsonTakeValue");
181 m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson"); 188 // m_comms.RegisterScriptInvocation(this, "JsonTakeValueJson");
182 189
183 m_comms.RegisterScriptInvocation(this,"JsonReadValue"); 190 // m_comms.RegisterScriptInvocation(this, "JsonReadValue");
184 m_comms.RegisterScriptInvocation(this,"JsonReadValueJson"); 191 // m_comms.RegisterScriptInvocation(this, "JsonReadValueJson");
185 192
186 m_comms.RegisterScriptInvocation(this,"JsonSetValue"); 193 // m_comms.RegisterScriptInvocation(this, "JsonSetValue");
187 m_comms.RegisterScriptInvocation(this,"JsonSetValueJson"); 194 // m_comms.RegisterScriptInvocation(this, "JsonSetValueJson");
188 195
189 m_comms.RegisterScriptInvocation(this,"JsonRemoveValue"); 196 // m_comms.RegisterScriptInvocation(this, "JsonRemoveValue");
190 } 197 }
191 catch (Exception e) 198 catch (Exception e)
192 { 199 {
193 // See http://opensimulator.org/mantis/view.php?id=5971 for more information 200 // See http://opensimulator.org/mantis/view.php?id=5971 for more information
194 m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message); 201 m_log.WarnFormat("[JsonStoreScripts]: script method registration failed; {0}", e.Message);
195 m_enabled = false; 202 m_enabled = false;
196 } 203 }
197 } 204 }
@@ -208,23 +215,45 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
208 215
209#endregion 216#endregion
210 217
218#region ScriptConstantInteface
219
220 [ScriptConstant]
221 public static readonly int JSONTYPEUNDEF = (int)JsonStoreNodeType.Undefined;
222
223 [ScriptConstant]
224 public static readonly int JSONTYPEOBJECT = (int)JsonStoreNodeType.Object;
225
226 [ScriptConstant]
227 public static readonly int JSONTYPEARRAY = (int)JsonStoreNodeType.Array;
228
229 [ScriptConstant]
230 public static readonly int JSONTYPEVALUE = (int)JsonStoreNodeType.Value;
231
232#endregion
233
211#region ScriptInvocationInteface 234#region ScriptInvocationInteface
212 // ----------------------------------------------------------------- 235 // -----------------------------------------------------------------
213 /// <summary> 236 /// <summary>
214 /// 237 ///
215 /// </summary> 238 /// </summary>
216 // ----------------------------------------------------------------- 239 // -----------------------------------------------------------------
217 protected void GenerateRuntimeError(string msg) 240 [ScriptInvocation]
241 public UUID JsonAttachObjectStore(UUID hostID, UUID scriptID)
218 { 242 {
219 throw new Exception("JsonStore Runtime Error: " + msg); 243 UUID uuid = UUID.Zero;
244 if (! m_store.AttachObjectStore(hostID))
245 GenerateRuntimeError("Failed to create Json store");
246
247 return hostID;
220 } 248 }
221 249
222 // ----------------------------------------------------------------- 250 // -----------------------------------------------------------------
223 /// <summary> 251 /// <summary>
224 /// 252 ///
225 /// </summary> 253 /// </summary>
226 // ----------------------------------------------------------------- 254 // -----------------------------------------------------------------
227 protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) 255 [ScriptInvocation]
256 public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
228 { 257 {
229 UUID uuid = UUID.Zero; 258 UUID uuid = UUID.Zero;
230 if (! m_store.CreateStore(value, ref uuid)) 259 if (! m_store.CreateStore(value, ref uuid))
@@ -238,7 +267,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
238 /// 267 ///
239 /// </summary> 268 /// </summary>
240 // ----------------------------------------------------------------- 269 // -----------------------------------------------------------------
241 protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) 270 [ScriptInvocation]
271 public int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID)
242 { 272 {
243 return m_store.DestroyStore(storeID) ? 1 : 0; 273 return m_store.DestroyStore(storeID) ? 1 : 0;
244 } 274 }
@@ -248,10 +278,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
248 /// 278 ///
249 /// </summary> 279 /// </summary>
250 // ----------------------------------------------------------------- 280 // -----------------------------------------------------------------
251 protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) 281 [ScriptInvocation]
282 public int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID)
283 {
284 return m_store.TestStore(storeID) ? 1 : 0;
285 }
286
287 // -----------------------------------------------------------------
288 /// <summary>
289 ///
290 /// </summary>
291 // -----------------------------------------------------------------
292 [ScriptInvocation]
293 public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
252 { 294 {
253 UUID reqID = UUID.Random(); 295 UUID reqID = UUID.Random();
254 Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); 296 Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier));
255 return reqID; 297 return reqID;
256 } 298 }
257 299
@@ -260,7 +302,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
260 /// 302 ///
261 /// </summary> 303 /// </summary>
262 // ----------------------------------------------------------------- 304 // -----------------------------------------------------------------
263 protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) 305 [ScriptInvocation]
306 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
264 { 307 {
265 UUID reqID = UUID.Random(); 308 UUID reqID = UUID.Random();
266 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); 309 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); });
@@ -272,12 +315,40 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
272 /// 315 ///
273 /// </summary> 316 /// </summary>
274 // ----------------------------------------------------------------- 317 // -----------------------------------------------------------------
275 protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) 318 [ScriptInvocation]
319 public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist)
320 {
321 string ipath = ConvertList2Path(pathlist);
322 string opath;
323
324 if (JsonStore.CanonicalPathExpression(ipath,out opath))
325 return opath;
326
327 // This won't parse if passed to the other routines as opposed to
328 // returning an empty string which is a valid path and would overwrite
329 // the entire store
330 return "**INVALID**";
331 }
332
333 // -----------------------------------------------------------------
334 /// <summary>
335 ///
336 /// </summary>
337 // -----------------------------------------------------------------
338 [ScriptInvocation]
339 public int JsonPathType(UUID hostID, UUID scriptID, UUID storeID, string path)
340 {
341 return (int)m_store.PathType(storeID,path);
342 }
343
344 [ScriptInvocation]
345 public int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path)
276 { 346 {
277 return m_store.TestPath(storeID,path,false) ? 1 : 0; 347 return m_store.TestPath(storeID,path,false) ? 1 : 0;
278 } 348 }
279 349
280 protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) 350 [ScriptInvocation]
351 public int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path)
281 { 352 {
282 return m_store.TestPath(storeID,path,true) ? 1 : 0; 353 return m_store.TestPath(storeID,path,true) ? 1 : 0;
283 } 354 }
@@ -287,12 +358,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
287 /// 358 ///
288 /// </summary> 359 /// </summary>
289 // ----------------------------------------------------------------- 360 // -----------------------------------------------------------------
290 protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) 361 [ScriptInvocation]
362 public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
291 { 363 {
292 return m_store.SetValue(storeID,path,value,false) ? 1 : 0; 364 return m_store.SetValue(storeID,path,value,false) ? 1 : 0;
293 } 365 }
294 366
295 protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) 367 [ScriptInvocation]
368 public int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
296 { 369 {
297 return m_store.SetValue(storeID,path,value,true) ? 1 : 0; 370 return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
298 } 371 }
@@ -302,7 +375,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
302 /// 375 ///
303 /// </summary> 376 /// </summary>
304 // ----------------------------------------------------------------- 377 // -----------------------------------------------------------------
305 protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) 378 [ScriptInvocation]
379 public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path)
306 { 380 {
307 return m_store.RemoveValue(storeID,path) ? 1 : 0; 381 return m_store.RemoveValue(storeID,path) ? 1 : 0;
308 } 382 }
@@ -312,14 +386,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
312 /// 386 ///
313 /// </summary> 387 /// </summary>
314 // ----------------------------------------------------------------- 388 // -----------------------------------------------------------------
315 protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) 389 [ScriptInvocation]
390 public int JsonArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path)
391 {
392 return m_store.ArrayLength(storeID,path);
393 }
394
395 // -----------------------------------------------------------------
396 /// <summary>
397 ///
398 /// </summary>
399 // -----------------------------------------------------------------
400 [ScriptInvocation]
401 public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path)
316 { 402 {
317 string value = String.Empty; 403 string value = String.Empty;
318 m_store.GetValue(storeID,path,false,out value); 404 m_store.GetValue(storeID,path,false,out value);
319 return value; 405 return value;
320 } 406 }
321 407
322 protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 408 [ScriptInvocation]
409 public string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
323 { 410 {
324 string value = String.Empty; 411 string value = String.Empty;
325 m_store.GetValue(storeID,path,true, out value); 412 m_store.GetValue(storeID,path,true, out value);
@@ -331,80 +418,105 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
331 /// 418 ///
332 /// </summary> 419 /// </summary>
333 // ----------------------------------------------------------------- 420 // -----------------------------------------------------------------
334 protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) 421 [ScriptInvocation]
422 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
335 { 423 {
336 UUID reqID = UUID.Random(); 424 UUID reqID = UUID.Random();
337 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); 425 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); });
338 return reqID; 426 return reqID;
339 } 427 }
340 428
341 protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 429 [ScriptInvocation]
430 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
342 { 431 {
343 UUID reqID = UUID.Random(); 432 UUID reqID = UUID.Random();
344 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); 433 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); });
345 return reqID; 434 return reqID;
346 } 435 }
347 436
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 // ----------------------------------------------------------------- 437 // -----------------------------------------------------------------
365 /// <summary> 438 /// <summary>
366 /// 439 ///
367 /// </summary> 440 /// </summary>
368 // ----------------------------------------------------------------- 441 // -----------------------------------------------------------------
369 protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) 442 [ScriptInvocation]
443 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
370 { 444 {
371 UUID reqID = UUID.Random(); 445 UUID reqID = UUID.Random();
372 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); 446 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); });
373 return reqID; 447 return reqID;
374 } 448 }
375 449
376 protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 450 [ScriptInvocation]
451 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
377 { 452 {
378 UUID reqID = UUID.Random(); 453 UUID reqID = UUID.Random();
379 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); 454 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); });
380 return reqID; 455 return reqID;
381 } 456 }
382 457
383 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) 458#endregion
459
460 // -----------------------------------------------------------------
461 /// <summary>
462 ///
463 /// </summary>
464 // -----------------------------------------------------------------
465 protected void GenerateRuntimeError(string msg)
466 {
467 m_log.InfoFormat("[JsonStore] runtime error: {0}",msg);
468 throw new Exception("JsonStore Runtime Error: " + msg);
469 }
470
471 // -----------------------------------------------------------------
472 /// <summary>
473 ///
474 /// </summary>
475 // -----------------------------------------------------------------
476 protected void DispatchValue(UUID scriptID, UUID reqID, string value)
477 {
478 m_comms.DispatchReply(scriptID,1,value,reqID.ToString());
479 }
480
481 // -----------------------------------------------------------------
482 /// <summary>
483 ///
484 /// </summary>
485 // -----------------------------------------------------------------
486 private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
384 { 487 {
385 try 488 try
386 { 489 {
387 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); 490 m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
388 return; 491 return;
389 } 492 }
390 catch (Exception e) 493 catch (Exception e)
391 { 494 {
392 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); 495 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
393 } 496 }
394 497
395 DispatchValue(scriptID,reqID,String.Empty); 498 DispatchValue(scriptID,reqID,String.Empty);
396 } 499 }
397 500
398#endregion
399 501
400 // ----------------------------------------------------------------- 502 // -----------------------------------------------------------------
401 /// <summary> 503 /// <summary>
402 /// 504 ///
403 /// </summary> 505 /// </summary>
404 // ----------------------------------------------------------------- 506 // -----------------------------------------------------------------
405 protected void DispatchValue(UUID scriptID, UUID reqID, string value) 507 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
406 { 508 {
407 m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); 509 try
510 {
511 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
512 return;
513 }
514 catch (Exception e)
515 {
516 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
517 }
518
519 DispatchValue(scriptID,reqID,String.Empty);
408 } 520 }
409 521
410 // ----------------------------------------------------------------- 522 // -----------------------------------------------------------------
@@ -412,31 +524,40 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
412 /// 524 ///
413 /// </summary> 525 /// </summary>
414 // ----------------------------------------------------------------- 526 // -----------------------------------------------------------------
415 private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) 527 private void DoJsonReadNotecard(
528 UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
416 { 529 {
530 UUID assetID;
531
532 if (!UUID.TryParse(notecardIdentifier, out assetID))
533 {
534 SceneObjectPart part = m_scene.GetSceneObjectPart(hostID);
535 assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard);
536 }
537
417 AssetBase a = m_scene.AssetService.Get(assetID.ToString()); 538 AssetBase a = m_scene.AssetService.Get(assetID.ToString());
418 if (a == null) 539 if (a == null)
419 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID)); 540 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID));
420 541
421 if (a.Type != (sbyte)AssetType.Notecard) 542 if (a.Type != (sbyte)AssetType.Notecard)
422 GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); 543 GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID));
423 544
424 m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID); 545 m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID);
425 546
426 try 547 try
427 { 548 {
428 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); 549 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
429 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; 550 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
430 m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); 551 m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
431 return; 552 return;
432 } 553 }
433 catch (Exception e) 554 catch (Exception e)
434 { 555 {
435 m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message); 556 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
436 } 557 }
437 558
438 GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); 559 GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID));
439 m_comms.DispatchReply(scriptID,0,"",reqID.ToString()); 560 m_comms.DispatchReply(scriptID, 0, "", reqID.ToString());
440 } 561 }
441 562
442 // ----------------------------------------------------------------- 563 // -----------------------------------------------------------------
@@ -494,5 +615,43 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
494 615
495 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); 616 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString());
496 } 617 }
618
619 // -----------------------------------------------------------------
620 /// <summary>
621 /// Convert a list of values that are path components to a single string path
622 /// </summary>
623 // -----------------------------------------------------------------
624 protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$");
625 private string ConvertList2Path(object[] pathlist)
626 {
627 string path = "";
628 for (int i = 0; i < pathlist.Length; i++)
629 {
630 string token = "";
631
632 if (pathlist[i] is string)
633 {
634 token = pathlist[i].ToString();
635
636 // Check to see if this is a bare number which would not be a valid
637 // identifier otherwise
638 if (m_ArrayPattern.IsMatch(token))
639 token = '[' + token + ']';
640 }
641 else if (pathlist[i] is int)
642 {
643 token = "[" + pathlist[i].ToString() + "]";
644 }
645 else
646 {
647 token = "." + pathlist[i].ToString() + ".";
648 }
649
650 path += token + ".";
651 }
652
653 return path;
654 }
655
497 } 656 }
498} 657} \ No newline at end of file
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..f25f290
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -0,0 +1,800 @@
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
57 [TestFixtureSetUp]
58 public void FixtureInit()
59 {
60 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
61 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
62 }
63
64 [TestFixtureTearDown]
65 public void TearDown()
66 {
67 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
68 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
69 // tests really shouldn't).
70 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
71 }
72
73 [SetUp]
74 public override void SetUp()
75 {
76 base.SetUp();
77
78 IConfigSource configSource = new IniConfigSource();
79 IConfig jsonStoreConfig = configSource.AddConfig("JsonStore");
80 jsonStoreConfig.Set("Enabled", "true");
81
82 m_engine = new MockScriptEngine();
83 m_smcm = new ScriptModuleCommsModule();
84 JsonStoreModule jsm = new JsonStoreModule();
85 JsonStoreScriptModule jssm = new JsonStoreScriptModule();
86
87 m_scene = new SceneHelpers().SetupScene();
88 SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm);
89
90 try
91 {
92 m_smcm.RegisterScriptInvocation(this, "DummyTestMethod");
93 }
94 catch (ArgumentException)
95 {
96 Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier.");
97 }
98
99 // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods.
100 }
101
102 private object InvokeOp(string name, params object[] args)
103 {
104 return InvokeOpOnHost(name, UUID.Zero, args);
105 }
106
107 private object InvokeOpOnHost(string name, UUID hostId, params object[] args)
108 {
109 return m_smcm.InvokeOperation(hostId, UUID.Zero, name, args);
110 }
111
112 [Test]
113 public void TestJsonCreateStore()
114 {
115 TestHelpers.InMethod();
116// TestHelpers.EnableLogging();
117
118 // Test blank store
119 {
120 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
121 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
122 }
123
124 // Test single element store
125 {
126 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
127 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
128 }
129
130 // Test with an integer value
131 {
132 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }");
133 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
134
135 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
136 Assert.That(value, Is.EqualTo("42.15"));
137 }
138
139 // Test with an array as the root node
140 {
141 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]");
142 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
143
144 string value = (string)InvokeOp("JsonGetValue", storeId, "[1]");
145 Assert.That(value, Is.EqualTo("two"));
146 }
147 }
148
149 [Test]
150 public void TestJsonDestroyStore()
151 {
152 TestHelpers.InMethod();
153// TestHelpers.EnableLogging();
154
155 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
156 int dsrv = (int)InvokeOp("JsonDestroyStore", storeId);
157
158 Assert.That(dsrv, Is.EqualTo(1));
159
160 int tprv = (int)InvokeOp("JsonTestPath", storeId, "Hello");
161 Assert.That(tprv, Is.EqualTo(0));
162 }
163
164 [Test]
165 public void TestJsonDestroyStoreNotExists()
166 {
167 TestHelpers.InMethod();
168// TestHelpers.EnableLogging();
169
170 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
171
172 int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId);
173
174 Assert.That(dsrv, Is.EqualTo(0));
175 }
176
177 [Test]
178 public void TestJsonGetValue()
179 {
180 TestHelpers.InMethod();
181// TestHelpers.EnableLogging();
182
183 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }");
184
185 {
186 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello.World");
187 Assert.That(value, Is.EqualTo("Two"));
188 }
189
190 // Test get of path section instead of leaf
191 {
192 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
193 Assert.That(value, Is.EqualTo(""));
194 }
195
196 // Test get of non-existing value
197 {
198 string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo");
199 Assert.That(fakeValueGet, Is.EqualTo(""));
200 }
201
202 // Test get from non-existing store
203 {
204 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
205 string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
206 Assert.That(fakeStoreValueGet, Is.EqualTo(""));
207 }
208 }
209
210 [Test]
211 public void TestJsonGetValueJson()
212 {
213 TestHelpers.InMethod();
214// TestHelpers.EnableLogging();
215
216 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }");
217
218 {
219 string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello.World");
220 Assert.That(value, Is.EqualTo("'Two'"));
221 }
222
223 // Test get of path section instead of leaf
224 {
225 string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello");
226 Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}"));
227 }
228
229 // Test get of non-existing value
230 {
231 string fakeValueGet = (string)InvokeOp("JsonGetValueJson", storeId, "foo");
232 Assert.That(fakeValueGet, Is.EqualTo(""));
233 }
234
235 // Test get from non-existing store
236 {
237 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
238 string fakeStoreValueGet = (string)InvokeOp("JsonGetValueJson", fakeStoreId, "Hello");
239 Assert.That(fakeStoreValueGet, Is.EqualTo(""));
240 }
241 }
242
243// [Test]
244// public void TestJsonTakeValue()
245// {
246// TestHelpers.InMethod();
247//// TestHelpers.EnableLogging();
248//
249// UUID storeId
250// = (UUID)m_smcm.InvokeOperation(
251// UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" });
252//
253// string value
254// = (string)m_smcm.InvokeOperation(
255// UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" });
256//
257// Assert.That(value, Is.EqualTo("World"));
258//
259// string value2
260// = (string)m_smcm.InvokeOperation(
261// UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
262//
263// Assert.That(value, Is.Null);
264// }
265
266 [Test]
267 public void TestJsonRemoveValue()
268 {
269 TestHelpers.InMethod();
270// TestHelpers.EnableLogging();
271
272 // Test remove of node in object pointing to a string
273 {
274 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
275
276 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
277 Assert.That(returnValue, Is.EqualTo(1));
278
279 int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
280 Assert.That(result, Is.EqualTo(0));
281
282 string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello");
283 Assert.That(returnValue2, Is.EqualTo(""));
284 }
285
286 // Test remove of node in object pointing to another object
287 {
288 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }");
289
290 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
291 Assert.That(returnValue, Is.EqualTo(1));
292
293 int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
294 Assert.That(result, Is.EqualTo(0));
295
296 string returnValue2 = (string)InvokeOp("JsonGetValueJson", storeId, "Hello");
297 Assert.That(returnValue2, Is.EqualTo(""));
298 }
299
300 // Test remove of node in an array
301 {
302 UUID storeId
303 = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }");
304
305 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]");
306 Assert.That(returnValue, Is.EqualTo(1));
307
308 int result = (int)InvokeOp("JsonTestPath", storeId, "Hello[0]");
309 Assert.That(result, Is.EqualTo(1));
310
311 result = (int)InvokeOp("JsonTestPath", storeId, "Hello[1]");
312 Assert.That(result, Is.EqualTo(0));
313
314 string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]");
315 Assert.That(stringReturnValue, Is.EqualTo("value2"));
316
317 stringReturnValue = (string)InvokeOp("JsonGetValueJson", storeId, "Hello[1]");
318 Assert.That(stringReturnValue, Is.EqualTo(""));
319 }
320
321 // Test remove of non-existing value
322 {
323 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
324
325 int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese");
326 Assert.That(fakeValueRemove, Is.EqualTo(0));
327 }
328
329 {
330 // Test get from non-existing store
331 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
332 int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello");
333 Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
334 }
335 }
336
337 [Test]
338 public void TestJsonTestPath()
339 {
340 TestHelpers.InMethod();
341// TestHelpers.EnableLogging();
342
343 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
344
345 {
346 int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World");
347 Assert.That(result, Is.EqualTo(1));
348 }
349
350 // Test for path which does not resolve to a value.
351 {
352 int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
353 Assert.That(result, Is.EqualTo(0));
354 }
355
356 {
357 int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo");
358 Assert.That(result2, Is.EqualTo(0));
359 }
360
361 // Test with fake store
362 {
363 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
364 int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello");
365 Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
366 }
367 }
368
369 [Test]
370 public void TestJsonTestPathJson()
371 {
372 TestHelpers.InMethod();
373// TestHelpers.EnableLogging();
374
375 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
376
377 {
378 int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World");
379 Assert.That(result, Is.EqualTo(1));
380 }
381
382 // Test for path which does not resolve to a value.
383 {
384 int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello");
385 Assert.That(result, Is.EqualTo(1));
386 }
387
388 {
389 int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo");
390 Assert.That(result2, Is.EqualTo(0));
391 }
392
393 // Test with fake store
394 {
395 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
396 int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello");
397 Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
398 }
399 }
400
401 [Test]
402 public void TestJsonSetValue()
403 {
404 TestHelpers.InMethod();
405// TestHelpers.EnableLogging();
406
407 {
408 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
409
410 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times");
411 Assert.That(result, Is.EqualTo(1));
412
413 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
414 Assert.That(value, Is.EqualTo("Times"));
415 }
416
417 // Commented out as this currently unexpectedly fails.
418 // Test setting a key containing periods with delineation
419// {
420// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
421//
422// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times");
423// Assert.That(result, Is.EqualTo(1));
424//
425// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}");
426// Assert.That(value, Is.EqualTo("Times"));
427// }
428
429 // *** Test [] ***
430
431 // Test setting a key containing unbalanced ] without delineation. Expecting failure
432 {
433 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
434
435 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times");
436 Assert.That(result, Is.EqualTo(0));
437
438 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus");
439 Assert.That(value, Is.EqualTo(""));
440 }
441
442 // Test setting a key containing unbalanced [ without delineation. Expecting failure
443 {
444 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
445
446 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times");
447 Assert.That(result, Is.EqualTo(0));
448
449 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus");
450 Assert.That(value, Is.EqualTo(""));
451 }
452
453 // Test setting a key containing unbalanced [] without delineation. Expecting failure
454 {
455 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
456
457 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times");
458 Assert.That(result, Is.EqualTo(0));
459
460 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus");
461 Assert.That(value, Is.EqualTo(""));
462 }
463
464 // Test setting a key containing unbalanced ] with delineation
465 {
466 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
467
468 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times");
469 Assert.That(result, Is.EqualTo(1));
470
471 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}");
472 Assert.That(value, Is.EqualTo("Times"));
473 }
474
475 // Test setting a key containing unbalanced [ with delineation
476 {
477 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
478
479 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times");
480 Assert.That(result, Is.EqualTo(1));
481
482 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}");
483 Assert.That(value, Is.EqualTo("Times"));
484 }
485
486 // Test setting a key containing empty balanced [] with delineation
487 {
488 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
489
490 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times");
491 Assert.That(result, Is.EqualTo(1));
492
493 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}");
494 Assert.That(value, Is.EqualTo("Times"));
495 }
496
497 // Commented out as this currently unexpectedly fails.
498// // Test setting a key containing brackets around an integer with delineation
499// {
500// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
501//
502// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times");
503// Assert.That(result, Is.EqualTo(1));
504//
505// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}");
506// Assert.That(value, Is.EqualTo("Times"));
507// }
508
509 // *** Test {} ***
510
511 // Test setting a key containing unbalanced } without delineation. Expecting failure (?)
512 {
513 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
514
515 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times");
516 Assert.That(result, Is.EqualTo(0));
517
518 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
519 Assert.That(value, Is.EqualTo(""));
520 }
521
522 // Test setting a key containing unbalanced { without delineation. Expecting failure (?)
523 {
524 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
525
526 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times");
527 Assert.That(result, Is.EqualTo(0));
528
529 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
530 Assert.That(value, Is.EqualTo(""));
531 }
532
533 // Commented out as this currently unexpectedly fails.
534// // Test setting a key containing unbalanced }
535// {
536// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
537//
538// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times");
539// Assert.That(result, Is.EqualTo(1));
540//
541// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun}Circus}");
542// Assert.That(value, Is.EqualTo("Times"));
543// }
544
545 // Test setting a key containing unbalanced { with delineation
546 {
547 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
548
549 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times");
550 Assert.That(result, Is.EqualTo(1));
551
552 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}");
553 Assert.That(value, Is.EqualTo("Times"));
554 }
555
556 // Test setting a key containing balanced {} with delineation. This should fail.
557 {
558 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
559
560 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times");
561 Assert.That(result, Is.EqualTo(0));
562
563 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}");
564 Assert.That(value, Is.EqualTo(""));
565 }
566
567 // Test setting to location that does not exist. This should fail.
568 {
569 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
570
571 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times");
572 Assert.That(result, Is.EqualTo(0));
573
574 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
575 Assert.That(value, Is.EqualTo(""));
576 }
577
578 // Test with fake store
579 {
580 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
581 int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World");
582 Assert.That(fakeStoreValueSet, Is.EqualTo(0));
583 }
584 }
585
586 [Test]
587 public void TestJsonSetValueJson()
588 {
589 TestHelpers.InMethod();
590// TestHelpers.EnableLogging();
591
592 // Single quoted token case
593 {
594 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
595
596 int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "'Times'");
597 Assert.That(result, Is.EqualTo(1));
598
599 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
600 Assert.That(value, Is.EqualTo("Times"));
601 }
602
603 // Sub-tree case
604 {
605 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
606
607 int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "{ 'Filled' : 'Times' }");
608 Assert.That(result, Is.EqualTo(1));
609
610 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled");
611 Assert.That(value, Is.EqualTo("Times"));
612 }
613
614 // If setting single strings in JsonSetValueJson, these must be single quoted tokens, not bare strings.
615 {
616 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
617
618 int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "Times");
619 Assert.That(result, Is.EqualTo(0));
620
621 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
622 Assert.That(value, Is.EqualTo(""));
623 }
624
625 // Test setting to location that does not exist. This should fail.
626 {
627 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
628
629 int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun.Circus", "'Times'");
630 Assert.That(result, Is.EqualTo(0));
631
632 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
633 Assert.That(value, Is.EqualTo(""));
634 }
635
636 // Test with fake store
637 {
638 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
639 int fakeStoreValueSet = (int)InvokeOp("JsonSetValueJson", fakeStoreId, "Hello", "'World'");
640 Assert.That(fakeStoreValueSet, Is.EqualTo(0));
641 }
642 }
643
644 /// <summary>
645 /// Test for writing json to a notecard
646 /// </summary>
647 /// <remarks>
648 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
649 /// it via the MockScriptEngine or perhaps by a dummy script instance.
650 /// </remarks>
651 [Test]
652 public void TestJsonWriteNotecard()
653 {
654 TestHelpers.InMethod();
655// TestHelpers.EnableLogging();
656
657 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
658 m_scene.AddSceneObject(so);
659
660 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
661
662 {
663 string notecardName = "nc1";
664
665 // Write notecard
666 UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName);
667 Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
668
669 TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName);
670 Assert.That(nc1Item, Is.Not.Null);
671
672 // TODO: Should independently check the contents.
673 }
674
675 // TODO: Write partial test
676
677 {
678 // Try to write notecard for a bad path
679 // In this case we do get a request id but no notecard is written.
680 string badPathNotecardName = "badPathNotecardName";
681
682 UUID writeNotecardBadPathRequestId
683 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "flibble", badPathNotecardName);
684 Assert.That(writeNotecardBadPathRequestId, Is.Not.EqualTo(UUID.Zero));
685
686 TaskInventoryItem badPathItem = so.RootPart.Inventory.GetInventoryItem(badPathNotecardName);
687 Assert.That(badPathItem, Is.Null);
688 }
689
690 {
691 // Test with fake store
692 // In this case we do get a request id but no notecard is written.
693 string fakeStoreNotecardName = "fakeStoreNotecardName";
694
695 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
696 UUID fakeStoreWriteNotecardValue
697 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName);
698 Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero));
699
700 TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName);
701 Assert.That(fakeStoreItem, Is.Null);
702 }
703 }
704
705 /// <summary>
706 /// Test for reading json from a notecard
707 /// </summary>
708 /// <remarks>
709 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
710 /// it via the MockScriptEngine or perhaps by a dummy script instance.
711 /// </remarks>
712 [Test]
713 public void TestJsonReadNotecard()
714 {
715 TestHelpers.InMethod();
716// TestHelpers.EnableLogging();
717
718 string notecardName = "nc1";
719
720 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
721 m_scene.AddSceneObject(so);
722
723 UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
724
725 // Write notecard
726 InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName);
727
728 {
729 // Read notecard
730 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
731 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName);
732 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
733
734 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
735 Assert.That(value, Is.EqualTo("World"));
736 }
737
738 {
739 // Read notecard to new single component path
740 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
741 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName);
742 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
743
744 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
745 Assert.That(value, Is.EqualTo(""));
746
747 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello");
748 Assert.That(value, Is.EqualTo("World"));
749 }
750
751 {
752 // Read notecard to new multi-component path. This should not work.
753 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
754 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
755 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
756
757 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
758 Assert.That(value, Is.EqualTo(""));
759
760 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
761 Assert.That(value, Is.EqualTo(""));
762 }
763
764 {
765 // Read notecard to existing multi-component path. This should work
766 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
767 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
768 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
769
770 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
771 Assert.That(value, Is.EqualTo(""));
772
773 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
774 Assert.That(value, Is.EqualTo("World"));
775 }
776
777 {
778 // Read notecard to invalid path. This should not work.
779 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
780 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName);
781 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
782
783 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
784 Assert.That(value, Is.EqualTo(""));
785 }
786
787 {
788 // Try read notecard to fake store.
789 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
790 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName);
791 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
792
793 string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
794 Assert.That(value, Is.EqualTo(""));
795 }
796 }
797
798 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
799 }
800} \ 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}