Skip to content

Commit fb40758

Browse files
committed
Fix FromJson and ToJson methods performance caused by json lib changes (#971)
* Fix FromJson and ToJson methods performance caused by json lib changes * Fix FromJson and ToJson methods performance caused by json lib changes (cherry picked from commit 0ac75dd) (cherry picked from commit a77fdb2)
1 parent 282d8b0 commit fb40758

File tree

5 files changed

+253
-4
lines changed

5 files changed

+253
-4
lines changed

common/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
<dependency>
5454
<groupId>org.json</groupId>
5555
<artifactId>json</artifactId>
56-
<version>20231013</version>
56+
<version>20250517</version>
5757
</dependency>
5858
</dependencies>
5959

common/src/main/java/com/genexus/GXBaseCollection.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public void FromJSONObject(Object obj)
233233
try
234234
{
235235
Object jsonObj = jsonArr.get(i);
236-
if (jsonObj instanceof JSONObject)
236+
if ((jsonObj instanceof JSONObject) && !(jsonObj instanceof JSONObjectWrapper))
237237
jsonObj = new JSONObjectWrapper((JSONObject)jsonObj);
238238
Class[] parTypes = new Class[] {};
239239
Object[] arglist = new Object[] {};

common/src/main/java/com/genexus/json/JSONTokenerWrapper.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,32 @@
44
import org.json.JSONException;
55

66
public class JSONTokenerWrapper extends JSONTokener{
7+
private String mySource;
8+
private int myIndex;
79

810
public JSONTokenerWrapper(String string) {
911
super(string);
12+
mySource = string;
13+
myIndex = 0;
14+
}
15+
16+
public void back() {
17+
if (myIndex > 0) {
18+
myIndex -= 1;
19+
}
20+
}
21+
22+
public boolean more() {
23+
return myIndex < mySource.length();
24+
}
25+
26+
public char next() {
27+
if (more()) {
28+
char c = mySource.charAt(myIndex);
29+
this.myIndex += 1;
30+
return c;
31+
}
32+
return 0;
1033
}
1134

1235
public Object nextValue() throws JSONException {

common/src/main/java/com/genexus/xml/GXXMLSerializable.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ public void FromJSONObject(Object obj)
363363
}
364364
else
365365
{
366-
if (obj instanceof JSONObject)
366+
if ((obj instanceof JSONObject) && !(obj instanceof JSONObjectWrapper))
367367
obj = new JSONObjectWrapper((JSONObject)obj);
368368
Iterator objIterator = getJSONObjectIterator((JSONObjectWrapper) obj);
369369
Iterator modifiedObjIterator = getFromJSONObjectOrderIterator(objIterator);
@@ -467,7 +467,7 @@ private void collectionFromJSONArray(JSONArray jsonArray, GXSimpleCollection gxC
467467
for(int i = 0; i < jsonArray.length(); i++)
468468
{
469469
Object currObj = jsonArray.get(i);
470-
if (currObj instanceof JSONObject)
470+
if ((currObj instanceof JSONObject) && !(currObj instanceof JSONObjectWrapper))
471471
currObj = new JSONObjectWrapper((JSONObject)currObj);
472472
if(currObj instanceof JSONObjectWrapper || !gxColl.IsSimpleCollection())
473473
{
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
package com.genexus.xml;
2+
3+
import com.genexus.ModelContext;
4+
import com.genexus.specific.java.Connect;
5+
import org.junit.Before;
6+
import org.junit.Test;
7+
8+
import static org.junit.Assert.*;
9+
10+
public class GXXMLSerializableTest {
11+
12+
private TestSerializable testObj;
13+
14+
@Before
15+
public void setUp() {
16+
Connect.init();
17+
testObj = new TestSerializable(new ModelContext(TestSerializable.class), "TestType");
18+
}
19+
20+
@Test
21+
public void testFromJSonStringWithSimpleFields() {
22+
// Arrange
23+
String json = "{\"stringField\":\"test value\",\"intField\":42,\"boolField\":true,\"doubleField\":3.14}";
24+
25+
// Act
26+
boolean result = testObj.fromJSonString(json);
27+
28+
// Assert
29+
assertTrue("JSON parsing should succeed", result);
30+
assertEquals("String field should match", "test value", testObj.getStringField());
31+
assertEquals("Int field should match", 42, testObj.getIntField());
32+
assertTrue("Boolean field should match", testObj.isBoolField());
33+
assertEquals("Double field should match", 3.14, testObj.getDoubleField(), 0.001);
34+
}
35+
36+
@Test
37+
public void testFromJSonStringWithNullFields() {
38+
// Arrange
39+
String json = "{\"stringField\":null,\"intField\":null,\"boolField\":null,\"doubleField\":null}";
40+
41+
// Act
42+
boolean result = testObj.fromJSonString(json);
43+
44+
// Assert
45+
assertTrue("JSON parsing should succeed", result);
46+
assertNull("String field should be null", testObj.getStringField());
47+
assertEquals("Int field should be default", 0, testObj.getIntField());
48+
assertFalse("Boolean field should be default", testObj.isBoolField());
49+
assertEquals("Double field should be default", 0.0, testObj.getDoubleField(), 0.001);
50+
}
51+
52+
@Test
53+
public void testFromJSonStringWithNestedObject() {
54+
// Arrange
55+
String json = "{\"stringField\":\"parent\",\"nestedObject\":{\"stringField\":\"child\"}}";
56+
57+
// Act
58+
boolean result = testObj.fromJSonString(json);
59+
60+
// Assert
61+
assertTrue("JSON parsing should succeed", result);
62+
assertEquals("Parent string field should match", "parent", testObj.getStringField());
63+
assertNotNull("Nested object should not be null", testObj.getNestedObject());
64+
assertEquals("Nested string field should match", "child", testObj.getNestedObject().getStringField());
65+
}
66+
67+
@Test
68+
public void testFromJSonStringWithCollection() {
69+
// Arrange
70+
String json = "{\"stringField\":\"parent\",\"items\":[{\"stringField\":\"item1\"},{\"stringField\":\"item2\"}]}";
71+
72+
// Act
73+
boolean result = testObj.fromJSonString(json);
74+
75+
// Assert
76+
assertTrue("JSON parsing should succeed", result);
77+
assertEquals("Parent string field should match", "parent", testObj.getStringField());
78+
assertNotNull("Items collection should not be null", testObj.getItems());
79+
assertEquals("Items collection should have correct size", 2, testObj.getItems().size());
80+
assertEquals("First item should match", "item1", (testObj.getItems().item(1)).getStringField());
81+
assertEquals("Second item should match", "item2", (testObj.getItems().item(2)).getStringField());
82+
}
83+
84+
@Test
85+
public void testFromJSonStringWithInvalidJson() {
86+
// Arrange
87+
String json = "{invalid json";
88+
89+
// Act
90+
boolean result = testObj.fromJSonString(json);
91+
92+
// Assert
93+
assertFalse("JSON parsing should fail", result);
94+
}
95+
96+
@Test
97+
public void testFromJSonStringWithEmptyJson() {
98+
// Arrange
99+
String json = "{}";
100+
101+
// Act
102+
boolean result = testObj.fromJSonString(json);
103+
104+
// Assert
105+
assertTrue("Empty JSON parsing should succeed", result);
106+
assertNull("String field should be null", testObj.getStringField());
107+
}
108+
109+
// Test implementation of GXXMLSerializable for testing purposes
110+
public static class TestSerializable extends GXXMLSerializable {
111+
private String stringField;
112+
private int intField;
113+
private boolean boolField;
114+
private double doubleField;
115+
private TestSerializable nestedObject;
116+
private TestSerializableCollection items;
117+
118+
public TestSerializable() {
119+
super(new ModelContext(TestSerializable.class), "TestType");
120+
}
121+
122+
public TestSerializable(ModelContext context) {
123+
super(context, "TestType");
124+
}
125+
126+
public TestSerializable(ModelContext context, String type) {
127+
super(context, type);
128+
}
129+
130+
@Override
131+
public String getJsonMap(String value) {
132+
return value;
133+
}
134+
135+
@Override
136+
public void initialize() {
137+
items = new TestSerializableCollection();
138+
}
139+
140+
// Getter and setter methods with patterns expected by GXXMLSerializable
141+
public String getgxTv_GXXMLSerializableTest$TestSerializable_StringField() {
142+
return stringField;
143+
}
144+
145+
public void setgxTv_GXXMLSerializableTest$TestSerializable_StringField(String value) {
146+
this.stringField = value;
147+
}
148+
149+
public int getgxTv_GXXMLSerializableTest$TestSerializable_IntField() {
150+
return intField;
151+
}
152+
153+
public void setgxTv_GXXMLSerializableTest$TestSerializable_IntField(int value) {
154+
this.intField = value;
155+
}
156+
157+
public boolean getgxTv_GXXMLSerializableTest$TestSerializable_BoolField() {
158+
return boolField;
159+
}
160+
161+
public void setgxTv_GXXMLSerializableTest$TestSerializable_BoolField(boolean value) {
162+
this.boolField = value;
163+
}
164+
165+
public double getgxTv_GXXMLSerializableTest$TestSerializable_DoubleField() {
166+
return doubleField;
167+
}
168+
169+
public void setgxTv_GXXMLSerializableTest$TestSerializable_DoubleField(double value) {
170+
this.doubleField = value;
171+
}
172+
173+
public TestSerializable getgxTv_GXXMLSerializableTest$TestSerializable_NestedObject() {
174+
return nestedObject;
175+
}
176+
177+
public void setgxTv_GXXMLSerializableTest$TestSerializable_NestedObject(TestSerializable value) {
178+
this.nestedObject = value;
179+
}
180+
181+
public TestSerializableCollection getgxTv_GXXMLSerializableTest$TestSerializable_Items() {
182+
return items;
183+
}
184+
185+
public void setgxTv_GXXMLSerializableTest$TestSerializable_Items(TestSerializableCollection value) {
186+
this.items = value;
187+
}
188+
189+
// Convenience getters for simpler test code
190+
public String getStringField() {
191+
return stringField;
192+
}
193+
194+
public int getIntField() {
195+
return intField;
196+
}
197+
198+
public boolean isBoolField() {
199+
return boolField;
200+
}
201+
202+
public double getDoubleField() {
203+
return doubleField;
204+
}
205+
206+
public TestSerializable getNestedObject() {
207+
return nestedObject;
208+
}
209+
210+
public TestSerializableCollection getItems() {
211+
return items;
212+
}
213+
}
214+
215+
// Collection class needed for collection tests
216+
public static class TestSerializableCollection extends com.genexus.GXSimpleCollection<TestSerializable> {
217+
public TestSerializableCollection() {
218+
super(TestSerializable.class, "TestSerializable", "TestCollection");
219+
}
220+
221+
@Override
222+
public TestSerializable item(int i) {
223+
return get(i-1);
224+
}
225+
}
226+
}

0 commit comments

Comments
 (0)