Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
<version>20250517</version>
</dependency>
</dependencies>

Expand Down
2 changes: 1 addition & 1 deletion common/src/main/java/com/genexus/GXBaseCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public void FromJSONObject(Object obj)
try
{
Object jsonObj = jsonArr.get(i);
if (jsonObj instanceof JSONObject)
if ((jsonObj instanceof JSONObject) && !(jsonObj instanceof JSONObjectWrapper))
jsonObj = new JSONObjectWrapper((JSONObject)jsonObj);
Class[] parTypes = new Class[] {};
Object[] arglist = new Object[] {};
Expand Down
23 changes: 23 additions & 0 deletions common/src/main/java/com/genexus/json/JSONTokenerWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,32 @@
import org.json.JSONException;

public class JSONTokenerWrapper extends JSONTokener{
private String mySource;
private int myIndex;

public JSONTokenerWrapper(String string) {
super(string);
mySource = string;
myIndex = 0;
}

public void back() {
if (myIndex > 0) {
myIndex -= 1;
}
}

public boolean more() {
return myIndex < mySource.length();
}

public char next() {
if (more()) {
char c = mySource.charAt(myIndex);
this.myIndex += 1;
return c;
}
return 0;
}

public Object nextValue() throws JSONException {
Expand Down
4 changes: 2 additions & 2 deletions common/src/main/java/com/genexus/xml/GXXMLSerializable.java
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ public void FromJSONObject(Object obj)
}
else
{
if (obj instanceof JSONObject)
if ((obj instanceof JSONObject) && !(obj instanceof JSONObjectWrapper))
obj = new JSONObjectWrapper((JSONObject)obj);
Iterator objIterator = getJSONObjectIterator((JSONObjectWrapper) obj);
Iterator modifiedObjIterator = getFromJSONObjectOrderIterator(objIterator);
Expand Down Expand Up @@ -467,7 +467,7 @@ private void collectionFromJSONArray(JSONArray jsonArray, GXSimpleCollection gxC
for(int i = 0; i < jsonArray.length(); i++)
{
Object currObj = jsonArray.get(i);
if (currObj instanceof JSONObject)
if ((currObj instanceof JSONObject) && !(currObj instanceof JSONObjectWrapper))
currObj = new JSONObjectWrapper((JSONObject)currObj);
if(currObj instanceof JSONObjectWrapper || !gxColl.IsSimpleCollection())
{
Expand Down
226 changes: 226 additions & 0 deletions java/src/test/java/com/genexus/xml/GXXMLSerializableTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
package com.genexus.xml;

import com.genexus.ModelContext;
import com.genexus.specific.java.Connect;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

public class GXXMLSerializableTest {

private TestSerializable testObj;

@Before
public void setUp() {
Connect.init();
testObj = new TestSerializable(new ModelContext(TestSerializable.class), "TestType");
}

@Test
public void testFromJSonStringWithSimpleFields() {
// Arrange
String json = "{\"stringField\":\"test value\",\"intField\":42,\"boolField\":true,\"doubleField\":3.14}";

// Act
boolean result = testObj.fromJSonString(json);

// Assert
assertTrue("JSON parsing should succeed", result);
assertEquals("String field should match", "test value", testObj.getStringField());
assertEquals("Int field should match", 42, testObj.getIntField());
assertTrue("Boolean field should match", testObj.isBoolField());
assertEquals("Double field should match", 3.14, testObj.getDoubleField(), 0.001);
}

@Test
public void testFromJSonStringWithNullFields() {
// Arrange
String json = "{\"stringField\":null,\"intField\":null,\"boolField\":null,\"doubleField\":null}";

// Act
boolean result = testObj.fromJSonString(json);

// Assert
assertTrue("JSON parsing should succeed", result);
assertNull("String field should be null", testObj.getStringField());
assertEquals("Int field should be default", 0, testObj.getIntField());
assertFalse("Boolean field should be default", testObj.isBoolField());
assertEquals("Double field should be default", 0.0, testObj.getDoubleField(), 0.001);
}

@Test
public void testFromJSonStringWithNestedObject() {
// Arrange
String json = "{\"stringField\":\"parent\",\"nestedObject\":{\"stringField\":\"child\"}}";

// Act
boolean result = testObj.fromJSonString(json);

// Assert
assertTrue("JSON parsing should succeed", result);
assertEquals("Parent string field should match", "parent", testObj.getStringField());
assertNotNull("Nested object should not be null", testObj.getNestedObject());
assertEquals("Nested string field should match", "child", testObj.getNestedObject().getStringField());
}

@Test
public void testFromJSonStringWithCollection() {
// Arrange
String json = "{\"stringField\":\"parent\",\"items\":[{\"stringField\":\"item1\"},{\"stringField\":\"item2\"}]}";

// Act
boolean result = testObj.fromJSonString(json);

// Assert
assertTrue("JSON parsing should succeed", result);
assertEquals("Parent string field should match", "parent", testObj.getStringField());
assertNotNull("Items collection should not be null", testObj.getItems());
assertEquals("Items collection should have correct size", 2, testObj.getItems().size());
assertEquals("First item should match", "item1", (testObj.getItems().item(1)).getStringField());
assertEquals("Second item should match", "item2", (testObj.getItems().item(2)).getStringField());
}

@Test
public void testFromJSonStringWithInvalidJson() {
// Arrange
String json = "{invalid json";

// Act
boolean result = testObj.fromJSonString(json);

// Assert
assertFalse("JSON parsing should fail", result);
}

@Test
public void testFromJSonStringWithEmptyJson() {
// Arrange
String json = "{}";

// Act
boolean result = testObj.fromJSonString(json);

// Assert
assertTrue("Empty JSON parsing should succeed", result);
assertNull("String field should be null", testObj.getStringField());
}

// Test implementation of GXXMLSerializable for testing purposes
public static class TestSerializable extends GXXMLSerializable {
private String stringField;
private int intField;
private boolean boolField;
private double doubleField;
private TestSerializable nestedObject;
private TestSerializableCollection items;

public TestSerializable() {
super(new ModelContext(TestSerializable.class), "TestType");
}

public TestSerializable(ModelContext context) {
super(context, "TestType");
}

public TestSerializable(ModelContext context, String type) {
super(context, type);
}

@Override
public String getJsonMap(String value) {
return value;
}

@Override
public void initialize() {
items = new TestSerializableCollection();
}

// Getter and setter methods with patterns expected by GXXMLSerializable
public String getgxTv_GXXMLSerializableTest$TestSerializable_StringField() {
return stringField;
}

public void setgxTv_GXXMLSerializableTest$TestSerializable_StringField(String value) {
this.stringField = value;
}

public int getgxTv_GXXMLSerializableTest$TestSerializable_IntField() {
return intField;
}

public void setgxTv_GXXMLSerializableTest$TestSerializable_IntField(int value) {
this.intField = value;
}

public boolean getgxTv_GXXMLSerializableTest$TestSerializable_BoolField() {
return boolField;
}

public void setgxTv_GXXMLSerializableTest$TestSerializable_BoolField(boolean value) {
this.boolField = value;
}

public double getgxTv_GXXMLSerializableTest$TestSerializable_DoubleField() {
return doubleField;
}

public void setgxTv_GXXMLSerializableTest$TestSerializable_DoubleField(double value) {
this.doubleField = value;
}

public TestSerializable getgxTv_GXXMLSerializableTest$TestSerializable_NestedObject() {
return nestedObject;
}

public void setgxTv_GXXMLSerializableTest$TestSerializable_NestedObject(TestSerializable value) {
this.nestedObject = value;
}

public TestSerializableCollection getgxTv_GXXMLSerializableTest$TestSerializable_Items() {
return items;
}

public void setgxTv_GXXMLSerializableTest$TestSerializable_Items(TestSerializableCollection value) {
this.items = value;
}

// Convenience getters for simpler test code
public String getStringField() {
return stringField;
}

public int getIntField() {
return intField;
}

public boolean isBoolField() {
return boolField;
}

public double getDoubleField() {
return doubleField;
}

public TestSerializable getNestedObject() {
return nestedObject;
}

public TestSerializableCollection getItems() {
return items;
}
}

// Collection class needed for collection tests
public static class TestSerializableCollection extends com.genexus.GXSimpleCollection<TestSerializable> {
public TestSerializableCollection() {
super(TestSerializable.class, "TestSerializable", "TestCollection");
}

@Override
public TestSerializable item(int i) {
return get(i-1);
}
}
}
Loading