Skip to content

Commit fd2e1fc

Browse files
committed
Merge pull request #11 from Learnosity/LRN-9276
Lrn 9276
2 parents f0f2da5 + 2a7eb72 commit fd2e1fc

File tree

9 files changed

+587
-138
lines changed

9 files changed

+587
-138
lines changed

LearnositySDK/Request/DataApi.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private Remote handleRequest(string url, Init init)
7070
/// <param name="secret">Private key</param>
7171
/// <param name="requestPacketJson">Request packet</param>
7272
/// <param name="action">Action for the request</param>
73-
/// <param name="callback">Callback to process JSON data</param>
73+
/// <param name="callback">Callback to process JSON data. Returning false in callback breaks from the loop of recursive requests.</param>
7474
/// <returns>Instance of the Remote class</returns>
7575
public JsonObject requestRecursive(string url, string securityPacketJson, string secret, string requestPacketJson = null, string action = null, ProcessData callback = null)
7676
{
@@ -93,7 +93,7 @@ public JsonObject requestRecursive(string url, string securityPacketJson, string
9393
/// <param name="secret">Private key</param>
9494
/// <param name="requestPacket">Request packet</param>
9595
/// <param name="action">Action for the request</param>
96-
/// <param name="callback">Callback to process JSON data</param>
96+
/// <param name="callback">Callback to process JSON data. Returning false in callback breaks from the loop of recursive requests.</param>
9797
/// <returns>Instance of the Remote class</returns>
9898
public JsonObject requestRecursive(string url, JsonObject securityPacket, string secret, JsonObject requestPacket = null, string action = null, ProcessData callback = null)
9999
{
@@ -108,7 +108,7 @@ public JsonObject requestRecursive(string url, JsonObject securityPacket, string
108108
/// <param name="secret">Private key</param>
109109
/// <param name="requestPacket">Request packet</param>
110110
/// <param name="action">Action for the request</param>
111-
/// <param name="callback">Callback to process JSON data</param>
111+
/// <param name="callback">Callback to process JSON data. Returning false in callback breaks from the loop of recursive requests.</param>
112112
/// <returns>Instance of the Remote class</returns>
113113
private JsonObject handleRequestRecursive(string url, JsonObject securityPacket, string secret, JsonObject requestPacket = null, string action = null, ProcessData callback = null)
114114
{
@@ -135,7 +135,11 @@ private JsonObject handleRequestRecursive(string url, JsonObject securityPacket,
135135
{
136136
if (callback != null)
137137
{
138-
callback(data.toJson());
138+
// return if callback returns false
139+
if (!callback(data.toJson()))
140+
{
141+
return response;
142+
}
139143
}
140144
else
141145
{

LearnositySDK/Utils/JsonObject.cs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,27 @@ public void set(bool value)
9090
this.arrayIndex++;
9191
}
9292

93+
/// <summary>
94+
/// Sets/adds the value
95+
/// </summary>
96+
/// <param name="key"></param>
97+
/// <param name="value"></param>
98+
public void set(JToken value)
99+
{
100+
this.set(this.arrayIndex, value);
101+
this.arrayIndex++;
102+
}
103+
104+
/// <summary>
105+
/// Sets/adds NULL
106+
/// </summary>
107+
/// <param name="key"></param>
108+
/// <param name="value"></param>
109+
public void setNull()
110+
{
111+
this.set(JToken.Parse("null"));
112+
}
113+
93114
/// <summary>
94115
/// Sets/adds value with given type
95116
/// </summary>
@@ -161,6 +182,16 @@ public void set(int key, JToken value)
161182
this.set(key.ToString(), value);
162183
}
163184

185+
/// <summary>
186+
/// Sets/adds NULL
187+
/// </summary>
188+
/// <param name="key"></param>
189+
/// <param name="value"></param>
190+
public void setNull(int key)
191+
{
192+
this.set(key, JToken.Parse("null"));
193+
}
194+
164195
/// <summary>
165196
/// Sets/adds the value
166197
/// </summary>
@@ -198,7 +229,7 @@ public void set(string key, string value)
198229
/// <param name="value"></param>
199230
public void set(string key, JsonObject value)
200231
{
201-
if (this.isArray())
232+
if (value.isArray())
202233
{
203234
this.set("JsonArray", key, value);
204235
}
@@ -218,6 +249,16 @@ public void set(string key, JToken value)
218249
this.set("NULL", key, value);
219250
}
220251

252+
/// <summary>
253+
/// Sets/adds NULL
254+
/// </summary>
255+
/// <param name="key"></param>
256+
/// <param name="value"></param>
257+
public void setNull(string key)
258+
{
259+
this.set(key, JToken.Parse("null"));
260+
}
261+
221262
/// <summary>
222263
/// Sets/adds the value
223264
/// </summary>
@@ -518,6 +559,8 @@ public string[] getKeys()
518559
l.Add(item.Key);
519560
}
520561

562+
l.Sort();
563+
521564
return l.ToArray();
522565
}
523566

@@ -593,6 +636,10 @@ public string toJson()
593636
{
594637
sb.Append(this.db[key].ToString().ToLower());
595638
}
639+
else if (this.dt.ContainsKey(key))
640+
{
641+
sb.Append("null");
642+
}
596643
else if (this.dj.ContainsKey(key))
597644
{
598645
sb.Append(this.dj[key].toJson());
@@ -601,10 +648,6 @@ public string toJson()
601648
{
602649
sb.Append(this.da[key].toJson());
603650
}
604-
else if (this.dt.ContainsKey(key))
605-
{
606-
sb.Append("null");
607-
}
608651
}
609652

610653
sb.Append("]");
@@ -663,19 +706,19 @@ public string toJson()
663706
index++;
664707
}
665708

666-
foreach (KeyValuePair<string, JsonObject> item in this.dj)
709+
foreach (KeyValuePair<string, JToken> item in this.dt)
667710
{
668711
if (index > 0)
669712
{
670713
sb.Append(",");
671714
}
672715

673-
sb.Append(Json.encode(item.Key) + ":" + item.Value.toJson());
716+
sb.Append(Json.encode(item.Key) + ":null");
674717

675718
index++;
676719
}
677720

678-
foreach (KeyValuePair<string, JsonObject> item in this.da)
721+
foreach (KeyValuePair<string, JsonObject> item in this.dj)
679722
{
680723
if (index > 0)
681724
{
@@ -687,14 +730,14 @@ public string toJson()
687730
index++;
688731
}
689732

690-
foreach (KeyValuePair<string, JToken> item in this.dt)
733+
foreach (KeyValuePair<string, JsonObject> item in this.da)
691734
{
692735
if (index > 0)
693736
{
694737
sb.Append(",");
695738
}
696739

697-
sb.Append(Json.encode(item.Key) + ":null");
740+
sb.Append(Json.encode(item.Key) + ":" + item.Value.toJson());
698741

699742
index++;
700743
}

LearnositySDK/Utils/JsonObjectFactory.cs

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Text;
55
using Newtonsoft.Json;
66
using Newtonsoft.Json.Linq;
7+
using System.IO;
78

89
namespace LearnositySDK.Utils
910
{
@@ -23,19 +24,19 @@ public static JsonObject fromString(string JSON)
2324
return null;
2425
}
2526

26-
if (type == "object")
27+
using (var sr = new StringReader(JSON))
28+
using (var jr = new JsonTextReader(sr) { DateParseHandling = DateParseHandling.None })
2729
{
28-
JObject jObject = JObject.Parse(JSON);
29-
return JsonObjectFactory.fromJObject(jObject);
30-
}
31-
else if (type == "array")
32-
{
33-
JArray jArray = JArray.Parse(JSON);
34-
return JsonObjectFactory.fromJArray(jArray);
35-
}
36-
else
37-
{
38-
throw new Exception("Type not recognized");
30+
JToken parsed = JToken.ReadFrom(jr);
31+
switch (parsed.Type)
32+
{
33+
case JTokenType.Object:
34+
return JsonObjectFactory.fromJObject((JObject)parsed);
35+
case JTokenType.Array:
36+
return JsonObjectFactory.fromJArray((JArray)parsed);
37+
default:
38+
throw new Exception("Currently we don't accept single values, only objects and arrays");
39+
}
3940
}
4041
}
4142

@@ -147,6 +148,7 @@ public static JsonObject merge(JsonObject obj1, JsonObject obj2, bool overwrite
147148
{
148149
JsonObject newObj = null;
149150

151+
// for arrays we just insert elements from the second array to the first one and return a new array
150152
if (obj1.isArray() && obj2.isArray())
151153
{
152154
newObj = JsonObjectFactory.mergeArrays(obj1, obj2);
@@ -164,68 +166,49 @@ public static JsonObject merge(JsonObject obj1, JsonObject obj2, bool overwrite
164166

165167
foreach (string key in keys)
166168
{
167-
if (recursive)
168-
{
169-
string type1 = "";
170-
string type2 = "";
171-
Object temp1Object = obj1.get(key, ref type1);
172-
Object temp2Object = obj2.get(key, ref type2);
173-
174-
// recursive merge makes sense only when both items are associative arrays
175-
// if not regular merge will be performed
176-
if (
177-
(type1 == "JsonObject" || type1 == "JsonArray") &&
178-
(type2 == "JsonObject" || type2 == "JsonArray") )
179-
{
180-
JsonObject temp1 = (JsonObject)temp1Object;
181-
JsonObject temp2 = (JsonObject)temp2Object;
182-
int temp1Count = temp1.count();
183-
int temp2Count = temp2.count();
184-
185-
if (temp1Count == 0 && temp2Count == 0)
186-
{
187-
type = "JsonObject";
188-
temp = new JsonObject();
189-
}
190-
else if(temp1Count == 0)
191-
{
192-
type = type2;
193-
temp = temp2;
194-
}
195-
else if(temp2Count == 0)
196-
{
197-
type = type1;
198-
temp = temp1;
199-
}
200-
else if (type1 == "JsonArray" && type2 == "JsonArray")
201-
{
202-
type = "JsonArray";
203-
temp = JsonObjectFactory.merge(temp1, temp2, overwrite, recursive);
204-
}
205-
else
206-
{
207-
type = "JsonObject";
208-
temp = JsonObjectFactory.merge(temp1, temp2, overwrite, recursive);
209-
}
169+
string type1 = "";
170+
string type2 = "";
171+
Object temp1Object = obj1.get(key, ref type1);
172+
Object temp2Object = obj2.get(key, ref type2);
210173

211-
newObj.set(type, key, temp);
212-
continue;
213-
}
174+
// recursive merging for objects only
175+
if (recursive && (type1 == "JsonObject" && type2 == "JsonObject"))
176+
{
177+
JsonObject temp1 = (JsonObject)temp1Object;
178+
JsonObject temp2 = (JsonObject)temp2Object;
179+
type = "JsonObject";
180+
temp = JsonObjectFactory.merge(temp1, temp2, overwrite, recursive);
214181
}
215-
216-
if (overwrite && Tools.in_array(key, keys2))
182+
// special treatment for arrays
183+
else if (type1 == "JsonArray" && type2 == "JsonArray")
184+
{
185+
JsonObject temp1 = (JsonObject)temp1Object;
186+
JsonObject temp2 = (JsonObject)temp2Object;
187+
type = "JsonArray";
188+
temp = JsonObjectFactory.merge(temp1, temp2);
189+
}
190+
// for the rest we simple insert the value depending on overwrite parameter
191+
// overwrite is enabled and value is in the second object
192+
else if (overwrite && Tools.in_array(key, keys2))
217193
{
218194
temp = obj2.get(key, ref type);
219195
}
196+
// value is in the first object
220197
else if (Tools.in_array(key, keys1))
221198
{
222199
temp = obj1.get(key, ref type);
223200
}
201+
// value is in the second object only
224202
else if (Tools.in_array(key, keys2))
225203
{
226204
temp = obj2.get(key, ref type);
227205
}
228206

207+
if (type == "JsonObject" || type == "JsonArray")
208+
{
209+
temp = ((JsonObject)temp).Clone();
210+
}
211+
229212
newObj.set(type, key, temp);
230213
continue;
231214
}
@@ -256,5 +239,16 @@ public static bool JSONEquality(JsonObject JSON1, JsonObject JSON2)
256239
{
257240
return JSONEquality(JSON1.toJson(), JSON2.toJson());
258241
}
242+
243+
/// <summary>
244+
/// Checks whether two JsonObjects are equal
245+
/// </summary>
246+
/// <param name="JSON1">first JsonObject to compare</param>
247+
/// <param name="JSON2">second JsonObject to compare</param>
248+
/// <returns></returns>
249+
public static bool JSONEquality(JsonObject JSON1, string JSON2)
250+
{
251+
return JSONEquality(JSON1.toJson(), JSON2);
252+
}
259253
}
260254
}

LearnositySDK/Utils/Tools.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace LearnositySDK.Utils
99
{
10-
class Tools
10+
public class Tools
1111
{
1212
/// <summary>
1313
/// Returns integer from hexadecimal representation

0 commit comments

Comments
 (0)