Skip to content

Commit

Permalink
Merge pull request #1148 from microsoft/andrueastman/serializerBug
Browse files Browse the repository at this point in the history
Fixes IllegalStateException when jsonarray is in additionalData
  • Loading branch information
andrueastman authored Apr 2, 2024
2 parents 46cd68f + 03d9d28 commit b907aaf
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 7 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

## [1.1.3] - 2024-04-02

### Changed

- Fixes a bug in the seriliazer that would `IllegalStateException` for json arrays in the additional data.

## [1.1.2] - 2024-03-26

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ public JsonParseNode(@Nonnull final JsonElement node) {
}
}

private <T> List<T> iterateOnArray(Function<JsonParseNode, T> fn) {
JsonArray array = currentNode.getAsJsonArray();
private <T> List<T> iterateOnArray(JsonElement jsonElement, Function<JsonParseNode, T> fn) {
JsonArray array = jsonElement.getAsJsonArray();
final Iterator<JsonElement> sourceIterator = array.iterator();
final List<T> result = new ArrayList<>();
while (sourceIterator.hasNext()) {
Expand All @@ -182,7 +182,8 @@ private <T> List<T> iterateOnArray(Function<JsonParseNode, T> fn) {
if (currentNode.isJsonNull()) {
return null;
} else if (currentNode.isJsonArray()) {
return iterateOnArray(itemNode -> getPrimitiveValue(targetClass, itemNode));
return iterateOnArray(
currentNode, itemNode -> getPrimitiveValue(targetClass, itemNode));
} else throw new RuntimeException("invalid state expected to have an array node");
}

Expand All @@ -192,7 +193,7 @@ private <T> List<T> iterateOnArray(Function<JsonParseNode, T> fn) {
if (currentNode.isJsonNull()) {
return null;
} else if (currentNode.isJsonArray()) {
return iterateOnArray(itemNode -> itemNode.getObjectValue(factory));
return iterateOnArray(currentNode, itemNode -> itemNode.getObjectValue(factory));
} else return null;
}

Expand All @@ -202,7 +203,7 @@ private <T> List<T> iterateOnArray(Function<JsonParseNode, T> fn) {
if (currentNode.isJsonNull()) {
return null;
} else if (currentNode.isJsonArray()) {
return iterateOnArray(itemNode -> itemNode.getEnumValue(enumParser));
return iterateOnArray(currentNode, itemNode -> itemNode.getEnumValue(enumParser));
} else throw new RuntimeException("invalid state expected to have an array node");
}

Expand Down Expand Up @@ -242,7 +243,7 @@ else if (element.isJsonPrimitive()) {
return new UntypedObject(propertiesMap);

} else if (element.isJsonArray()) {
return new UntypedArray(iterateOnArray(JsonParseNode::getUntypedValue));
return new UntypedArray(iterateOnArray(element, JsonParseNode::getUntypedValue));
}

throw new RuntimeException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import static org.junit.jupiter.api.Assertions.*;

import com.google.gson.JsonParser;
import com.microsoft.kiota.serialization.mocks.MyEnum;
import com.microsoft.kiota.serialization.mocks.TestEntity;
import com.microsoft.kiota.serialization.mocks.UntypedTestEntity;

import org.junit.jupiter.api.Test;
Expand All @@ -16,6 +18,11 @@
class JsonParseNodeTests {
private static final JsonParseNodeFactory _parseNodeFactory = new JsonParseNodeFactory();
private static final String contentType = "application/json";

private static final String testJsonString =
"{\"displayName\":\"My"
+ " Group\",\"phones\":[\"+1234567890\"],\"myEnum\":\"VALUE1\",\"enumCollection\":[\"VALUE1\"],\"id\":\"11111111-1111-1111-1111-111111111111"
+ "\",\"members@delta\":[{\"@odata.type\":\"#microsoft.graph.user\",\"id\":\"22222222-2222-2222-2222-222222222222\"}]}";
private static final String testUntypedJson =
"{\r\n"
+ " \"@odata.context\":"
Expand Down Expand Up @@ -95,6 +102,20 @@ void testInvalidOffsetDateTimeStringThrowsException(final String dateTimeString)
}
}

@Test
void getEntityWithArrayInAdditionalData() throws UnsupportedEncodingException {
final var rawResponse = new ByteArrayInputStream(testJsonString.getBytes("UTF-8"));
final var parseNode = _parseNodeFactory.getParseNode(contentType, rawResponse);
// Act
var entity = parseNode.getObjectValue(TestEntity::createFromDiscriminatorValue);
assertEquals("11111111-1111-1111-1111-111111111111", entity.getId());
assertEquals(1, entity.getPhones().size());
assertEquals(MyEnum.MY_VALUE1, entity.getMyEnum());
assertEquals(1, entity.getEnumCollection().size());
final var arrayValue = (UntypedArray) entity.getAdditionalData().get("members@delta");
assertEquals(1, arrayValue.getValue().spliterator().estimateSize());
}

@Test
void GetEntityWithUntypedNodesFromJson() throws UnsupportedEncodingException {
final var rawResponse = new ByteArrayInputStream(testUntypedJson.getBytes("UTF-8"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
Expand All @@ -25,6 +27,16 @@ public void setId(String _id) {
this._id = _id;
}

private List<String> _phones;

public List<String> getPhones() {
return _phones;
}

public void setPhones(List<String> _phones) {
this._phones = new ArrayList<String>(_phones);
}

private String _officeLocation;

public String getOfficeLocation() {
Expand Down Expand Up @@ -85,6 +97,16 @@ public void setMyEnum(MyEnum value) {
this._myEnum = value;
}

private List<MyEnum> _enumCollection;

public List<MyEnum> getEnumCollection() {
return _enumCollection;
}

public void setEnumCollection(List<MyEnum> value) {
this._enumCollection = new ArrayList<MyEnum>(value);
}

private OffsetDateTime _createdDateTime;

public OffsetDateTime getCreatedDateTime() {
Expand Down Expand Up @@ -134,11 +156,21 @@ public Map<String, Consumer<ParseNode>> getFieldDeserializers() {
(n) -> {
setMyEnum(n.getEnumValue(MyEnum::forValue));
});
put(
"enumCollection",
(n) -> {
setEnumCollection(n.getCollectionOfEnumValues(MyEnum::forValue));
});
put(
"createdDateTime",
(n) -> {
setCreatedDateTime(n.getOffsetDateTimeValue());
});
put(
"phones",
(n) -> {
setPhones(n.getCollectionOfPrimitiveValues(String.class));
});
}
};
}
Expand All @@ -153,7 +185,9 @@ public void serialize(SerializationWriter writer) {
writer.writeLocalTimeValue("startWorkTime", getStartWorkTime());
writer.writeLocalTimeValue("endWorkTime", getEndWorkTime());
writer.writeEnumValue("myEnum", getMyEnum());
writer.writeCollectionOfEnumValues("enumCollection", getEnumCollection());
writer.writeOffsetDateTimeValue("createdDateTime", getCreatedDateTime());
writer.writeCollectionOfPrimitiveValues("phones", getPhones());
writer.writeAdditionalData(getAdditionalData());
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ org.gradle.caching=true
mavenGroupId = com.microsoft.kiota
mavenMajorVersion = 1
mavenMinorVersion = 1
mavenPatchVersion = 2
mavenPatchVersion = 3
mavenArtifactSuffix =

#These values are used to run functional tests
Expand Down

0 comments on commit b907aaf

Please sign in to comment.