Skip to content

Commit

Permalink
Simplifying array processing in json-io
Browse files Browse the repository at this point in the history
  • Loading branch information
jdereg committed Oct 17, 2024
1 parent 93d6bf3 commit db3c717
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 65 deletions.
17 changes: 7 additions & 10 deletions src/main/java/com/cedarsoftware/io/JsonObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public boolean isArray() {
// Return the array that this JSON object wraps. This is used when there is a Collection class (like ArrayList)
// represented in the JSON. This also occurs if a specified array type is used (not Object[], but Integer[], for
// example).
public Object[] getJsonArray() {
return (Object[]) get(ITEMS);
public Object getJsonArray() {
return get(ITEMS);
}

public void setJsonArray(Object[] jsonArray) {
Expand All @@ -98,8 +98,8 @@ public int getLength() {
private Integer getLenientSize() {
if (isArray()) {
if (target == null) {
Object[] items = getJsonArray();
return items == null ? 0 : items.length;
Object items = getJsonArray();
return items == null ? 0 : Array.getLength(items);
}
if (char[].class.isAssignableFrom(target.getClass())) {
// Verify this for Character[]
Expand All @@ -108,8 +108,8 @@ private Integer getLenientSize() {
return Array.getLength(target);
}
if (isCollection() || isMap()) {
Object[] items = getJsonArray();
return items == null ? 0 : items.length;
Object items = getJsonArray();
return items == null ? 0 : Array.getLength(items);
}
return null;
}
Expand All @@ -128,10 +128,7 @@ public boolean hasValue() {

public int size() {
if (containsKey(ITEMS)) {
if (getJsonArray() == null) {
return 0;
}
return getJsonArray().length;
return getLength();
}

return jsonStore.size();
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/cedarsoftware/io/JsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,11 @@ private Object readArray(Class<?> suggestedType) throws IOException {
}

--curParseDepth;


// JsonObject jsonArray = new JsonObject();
// jsonArray.setJsonArray(list.toArray());
// jsonArray.setTarget(Array.newInstance(suggestedType == null ? Object.class : suggestedType, list.size()));
// return jsonArray;
if (suggestedType == null || suggestedType == Object.class) {
// No suggested type, so use Object[]
return list.toArray();
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/cedarsoftware/io/JsonReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,6 @@ public <T> T readObject(Class<T> rootType) {
throw new JsonIoException(getErrorMessage("error parsing JSON value"), e);
}

// JSON {} at root
if (returnValue instanceof JsonObject) {
return determineReturnValueWhenJsonObjectRoot(rootType, returnValue);
}

// JSON [] at root
if (returnValue instanceof Object[]) {
JsonObject rootObj = new JsonObject();
Expand All @@ -232,6 +227,11 @@ public <T> T readObject(Class<T> rootType) {
return asMaps ? returnValue : graph;
}

// JSON {} at root
if (returnValue instanceof JsonObject) {
return determineReturnValueWhenJsonObjectRoot(rootType, returnValue);
}

// JSON Primitive (String, Boolean, Double, Long), or convertible types
if (rootType != null) {
Converter converter = resolver.getConverter();
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/cedarsoftware/io/JsonWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -974,11 +974,11 @@ private void writeJsonObjectArray(JsonObject jObj, boolean showType) throws IOEx
}
tabIn();

Object[] items = jObj.getJsonArray();
Object items = jObj.getJsonArray();
final int lenMinus1 = len - 1;

for (int i = 0; i < len; i++) {
final Object value = items[i];
final Object value = Array.get(items, i);

if (value == null) {
output.write("null");
Expand Down Expand Up @@ -1053,13 +1053,13 @@ private void writeJsonObjectCollection(JsonObject jObj, boolean showType) throws

beginCollection(showType, referenced);

Object[] items = jObj.getJsonArray();
final int itemsLen = items.length;
Object items = jObj.getJsonArray();
final int itemsLen = Array.getLength(items);
final int itemsLenMinus1 = itemsLen - 1;

for (int i=0; i < itemsLen; i++)
{
writeCollectionElement(items[i]);
writeCollectionElement(Array.get(items, i));

if (i != itemsLenMinus1)
{
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/com/cedarsoftware/io/MapResolver.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cedarsoftware.io;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
Expand Down Expand Up @@ -137,16 +138,16 @@ public void traverseFields(final JsonObject jsonObj)
*/
protected void traverseCollection(final JsonObject jsonObj)
{
final Object[] items = jsonObj.getJsonArray();
if (items == null || items.length == 0) {
final Object items = jsonObj.getJsonArray();
if (items == null || Array.getLength(items) == 0) {
return;
}

Converter converter = getConverter();
int len = items.length;
int len = Array.getLength(items);

for (int i=0; i < len; i++) {
Object element = items[i];
Object element = Array.get(items, i);

if (element instanceof Object[]) { // array element inside Collection
JsonObject jsonObject = new JsonObject();
Expand All @@ -163,7 +164,7 @@ protected void traverseCollection(final JsonObject jsonObj)
// will be placed on the value-side of the Map
Class<?> type = jsonObject.getJavaType();
if (type != null && converter.isConversionSupportedFor(Map.class, type)) {
items[i] = converter.convert(jsonObject, type);
Array.set(items, i, converter.convert(jsonObject, type));
jsonObject.setFinished();
} else {
push(jsonObject);
Expand All @@ -174,9 +175,9 @@ protected void traverseCollection(final JsonObject jsonObj)

if (type != null && converter.isConversionSupportedFor(Map.class, type)) {
refObject.setFinishedTarget(converter.convert(refObject, type), true);
items[i] = refObject.getTarget();
Array.set(items, i, refObject.getTarget());
} else {
items[i] = refObject;
Array.set(items, i, refObject);
}
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/main/java/com/cedarsoftware/io/ObjectResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ private static String safeToString(Object o)
*/
protected void traverseCollection(final JsonObject jsonObj)
{
Object[] items = jsonObj.getJsonArray();
Object items = jsonObj.getJsonArray();

Class mayEnumClass = null;
String mayEnumClasName = (String)jsonObj.get("@enum");
Expand All @@ -286,7 +286,9 @@ protected void traverseCollection(final JsonObject jsonObj)
int idx = 0;

if (items != null) {
for (final Object element : items) {
int len = Array.getLength(items);
for (int i=0; i < len; i++) {
Object element = Array.get(items, i);
Object special;
if (element == null) {
col.add(null);
Expand Down Expand Up @@ -353,11 +355,11 @@ protected void traverseArray(final JsonObject jsonObj)

final Object array = jsonObj.getTarget();
final Class compType = array.getClass().getComponentType();
final Object[] jsonItems = jsonObj.getJsonArray();
final Object jsonItems = jsonObj.getJsonArray();
// Primitive arrays never make it here, as the ArrayFactory (ClassFactory) processes them in assignField.

for (int i = 0; i < len; i++) {
final Object element = jsonItems[i];
final Object element = Array.get(jsonItems, i);
Object special;

if (element == null) {
Expand Down Expand Up @@ -575,9 +577,11 @@ private void markUntypedObjects(final Type type, final Object rhs, final Class<?
}
} else if (instance instanceof JsonObject) {
final JsonObject jObj = (JsonObject) instance;
final Object[] array = jObj.getJsonArray();
final Object array = jObj.getJsonArray();
if (array != null) {
for (Object o : array) {
int len = Array.getLength(array);
for (int i=0; i < len; i++) {
Object o = Array.get(array, i);
stack2.addFirst(new Object[]{typeArgs[0], o});
}
}
Expand Down
35 changes: 20 additions & 15 deletions src/main/java/com/cedarsoftware/io/Resolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,9 @@ Object createInstance(JsonObject jsonObj) {
}

// Arrays
Object[] items = jsonObj.getJsonArray();
Object items = jsonObj.getJsonArray();
if (c.isArray() || (items != null && c == Object.class && !jsonObj.containsKey(KEYS))) { // Handle []
int size = (items == null) ? 0 : items.length;
int size = (items == null) ? 0 : Array.getLength(items);
mate = Array.newInstance(c.isArray() ? c.getComponentType() : Object.class, size);
jsonObj.setTarget(mate);
return mate;
Expand Down Expand Up @@ -498,8 +498,8 @@ private EnumSet<?> extractEnumSet(JsonObject jsonObj) {
? evaluateEnumSetTypeFromItems(jsonObj)
: ClassUtilities.forName(enumClassName, readOptions.getClassLoader());

Object[] items = jsonObj.getJsonArray();
if (items == null || items.length == 0) {
Object items = jsonObj.getJsonArray();
if (items == null || Array.getLength(items) == 0) {
if (enumClass != null) {
return EnumSet.noneOf(enumClass);
} else {
Expand All @@ -510,7 +510,9 @@ private EnumSet<?> extractEnumSet(JsonObject jsonObj) {
}

EnumSet enumSet = null;
for (Object item : items) {
int len = Array.getLength(items);
for (int i=0; i < len; i++) {
Object item = Array.get(items, i);
Enum enumItem;
if (item instanceof String) {
enumItem = Enum.valueOf(enumClass, (String) item);
Expand Down Expand Up @@ -541,10 +543,11 @@ private EnumSet<?> extractEnumSet(JsonObject jsonObj) {
*}</pre>
*/
private Class<?> evaluateEnumSetTypeFromItems(final JsonObject json) {
final Object[] items = json.getJsonArray();
if (items != null && items.length != 0) {
if (items[0] instanceof JsonObject) {
return ((JsonObject) items[0]).getJavaType();
final Object items = json.getJsonArray();
if (items != null && Array.getLength(items) != 0) {
Object value = Array.get(items, 0);
if (value instanceof JsonObject) {
return ((JsonObject) value).getJavaType();
}
}

Expand Down Expand Up @@ -617,23 +620,25 @@ public boolean valueToTarget(JsonObject jsonObject) {
// TODO: Support multiple dimensions
// TODO: Support char
if (jsonObject.javaType.isArray() && isConvertable(jsonObject.javaType.getComponentType())) {
Object[] jsonItems = jsonObject.getJsonArray();
Object jsonItems = jsonObject.getJsonArray();
Class<?> componentType = jsonObject.javaType.getComponentType();
if (jsonItems == null) { // empty array
jsonObject.setFinishedTarget(null, true);
return true;
}
Object javaArray = Array.newInstance(componentType, jsonItems.length);
for (int i = 0; i < jsonItems.length; i++) {
int len = Array.getLength(jsonItems);
Object javaArray = Array.newInstance(componentType, len);
for (int i = 0; i < len; i++) {
try {
Class<?> type = componentType;
if (jsonItems[i] instanceof JsonObject) {
JsonObject jObj = (JsonObject) jsonItems[i];
Object item = Array.get(jsonItems, i);
if (item instanceof JsonObject) {
JsonObject jObj = (JsonObject) item;
if (jObj.getJavaType() != null) {
type = jObj.getJavaType();
}
}
Array.set(javaArray, i, converter.convert(jsonItems[i], type));
Array.set(javaArray, i, converter.convert(item, type));
} catch (Exception e) {
JsonIoException jioe = new JsonIoException(e.getMessage());
jioe.setStackTrace(e.getStackTrace());
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/cedarsoftware/io/factory/ArrayFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ public ArrayFactory(Class<T> c) {
}

public T newInstance(Class<?> c, JsonObject jObj, Resolver resolver) {
Object[] items = jObj.getJsonArray();
Object items = jObj.getJsonArray();
Converter converter = resolver.getConverter();
if (items == null) {
jObj.setTarget(null);
return null;
}
int len = items.length;
int len = Array.getLength(items);
Class<?> arrayType = getType();
Class<?> componentType = arrayType.getComponentType();
Object array = Array.newInstance(componentType, len);

for (int i = 0; i < len; i++) {
Object val = items[i];
Object val = Array.get(items, i);
if (val == null) {
} else if (val instanceof JsonObject) {
Class<?> type;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.cedarsoftware.io.factory;

import java.lang.reflect.Array;

import com.cedarsoftware.io.JsonIoException;
import com.cedarsoftware.io.JsonObject;
import com.cedarsoftware.io.Resolver;
Expand Down Expand Up @@ -28,18 +30,21 @@ public CharacterPrimArrayFactory() {
}

public char[] newInstance(Class<?> c, JsonObject jObj, Resolver resolver) {
Object[] items = jObj.getJsonArray();
Object items = jObj.getJsonArray();
Object value;

if (items == null) {
value = null;
} else if (items.length == 0) {
value = new char[0];
} else if (items.length == 1) {
String s = (String) items[0];
value = s.toCharArray();
} else {
throw new JsonIoException("char[] should only have one String in the [], found " + items.length + ", line " + jObj.getLine() + ", col " + jObj.getCol());
int len = Array.getLength(items);
if (len == 0) {
value = new char[0];
} else if (len == 1) {
String s = (String) Array.get(items, 0);
value = s.toCharArray();
} else {
throw new JsonIoException("char[] should only have one String in the [], found " + len + ", line " + jObj.getLine() + ", col " + jObj.getCol());
}
}
jObj.setTarget(value);
return (char[]) jObj.getTarget();
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/cedarsoftware/io/ArrayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ void testReconstituteEmptyArray()
JsonObject e1 = (JsonObject) list[0];
JsonObject e2 = (JsonObject) list[1];
assertEquals(e1.getJsonArray(), e2.getJsonArray());
assertEquals(0, e1.getJsonArray().length);
assertEquals(0, e1.getLength());

json1 = TestUtil.toJson(list);
TestUtil.printLine("json1=" + json1);
Expand Down
9 changes: 5 additions & 4 deletions src/test/java/com/cedarsoftware/io/MapOfMapsTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.cedarsoftware.io;

import java.awt.*;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
Expand Down Expand Up @@ -519,10 +520,10 @@ public void testRefToArrayInMapOfMaps()
assert array[0] == array[1]; // Same instance of List
JsonObject objList1 = (JsonObject) array[0];
assert objList1.isArray();
Object[] list1 = objList1.getJsonArray();
assert list1[0] == list1[1]; // Same Person instance
assert list1[0] != list1[2]; // Not same Person instance
assert DeepEquals.deepEquals(list1[2], list1[1]); // Although difference instance, same contents
Object list1 = objList1.getJsonArray();
assert Array.get(list1, 0) == Array.get(list1, 1); // Same Person instance
assert Array.get(list1, 0) != Array.get(list1, 2); // Not same Person instance
assert DeepEquals.deepEquals(Array.get(list1, 2), Array.get(list1, 1)); // Although difference instance, same contents

Map objList2 = (Map) array[1];
assert objList1 == objList2; // Same JsonObject instance
Expand Down

0 comments on commit db3c717

Please sign in to comment.