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