Skip to content

Commit 2b7a0e2

Browse files
authored
Merge pull request #188 from microsoft/andrueastman/collections
Support rendering collection of values
2 parents c5c1902 + 87205c5 commit 2b7a0e2

File tree

7 files changed

+120
-7
lines changed

7 files changed

+120
-7
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Changed
1313

14+
## [0.3.0] - 2023-02-21
15+
16+
### Changed
17+
18+
- Adds support for serializing collections of primitive values in form serialization writer and form parse node
19+
1420
## [0.2.1] - 2023-01-13
1521

1622
### Changed

components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormParseNode.java

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.microsoft.kiota.serialization;
22

3+
import com.google.common.collect.Lists;
4+
35
import java.io.UnsupportedEncodingException;
46
import java.lang.reflect.InvocationTargetException;
57
import java.math.BigDecimal;
@@ -10,9 +12,11 @@
1012
import java.time.OffsetDateTime;
1113
import java.time.Period;
1214
import java.util.ArrayList;
15+
import java.util.Arrays;
1316
import java.util.Base64;
1417
import java.util.EnumSet;
1518
import java.util.HashMap;
19+
import java.util.Iterator;
1620
import java.util.List;
1721
import java.util.Locale;
1822
import java.util.Map;
@@ -178,7 +182,60 @@ public Period getPeriodValue() {
178182
}
179183
@Nullable
180184
public <T> List<T> getCollectionOfPrimitiveValues(@Nonnull final Class<T> targetClass) {
181-
throw new RuntimeException("deserialization of collections of is not supported with form encoding");
185+
final List<String> primitiveStringCollection = Arrays.asList(getStringValue().split(","));
186+
final Iterator<String> sourceIterator = primitiveStringCollection.iterator();
187+
final FormParseNode _this = this;
188+
return Lists.newArrayList(new Iterable<T>() {
189+
@Override
190+
public Iterator<T> iterator() {
191+
return new Iterator<T>(){
192+
@Override
193+
public boolean hasNext() {
194+
return sourceIterator.hasNext();
195+
}
196+
@Override
197+
@SuppressWarnings("unchecked")
198+
public T next() {
199+
final String item = sourceIterator.next();
200+
final Consumer<Parsable> onBefore = _this.getOnBeforeAssignFieldValues();
201+
final Consumer<Parsable> onAfter = _this.getOnAfterAssignFieldValues();
202+
final FormParseNode itemNode = new FormParseNode(item) {{
203+
this.setOnBeforeAssignFieldValues(onBefore);
204+
this.setOnAfterAssignFieldValues(onAfter);
205+
}};
206+
if(targetClass == Boolean.class) {
207+
return (T)itemNode.getBooleanValue();
208+
} else if(targetClass == Short.class) {
209+
return (T)itemNode.getShortValue();
210+
} else if(targetClass == Byte.class) {
211+
return (T)itemNode.getByteValue();
212+
} else if(targetClass == BigDecimal.class) {
213+
return (T)itemNode.getBigDecimalValue();
214+
} else if(targetClass == String.class) {
215+
return (T)itemNode.getStringValue();
216+
} else if(targetClass == Integer.class) {
217+
return (T)itemNode.getIntegerValue();
218+
} else if(targetClass == Float.class) {
219+
return (T)itemNode.getFloatValue();
220+
} else if(targetClass == Long.class) {
221+
return (T)itemNode.getLongValue();
222+
} else if(targetClass == UUID.class) {
223+
return (T)itemNode.getUUIDValue();
224+
} else if(targetClass == OffsetDateTime.class) {
225+
return (T)itemNode.getOffsetDateTimeValue();
226+
} else if(targetClass == LocalDate.class) {
227+
return (T)itemNode.getLocalDateValue();
228+
} else if(targetClass == LocalTime.class) {
229+
return (T)itemNode.getLocalTimeValue();
230+
} else if(targetClass == Period.class) {
231+
return (T)itemNode.getPeriodValue();
232+
} else {
233+
throw new RuntimeException("unknown type to deserialize " + targetClass.getName());
234+
}
235+
}
236+
};
237+
}
238+
});
182239
}
183240
@Nullable
184241
public <T extends Parsable> List<T> getCollectionOfObjectValues(@Nonnull final ParsableFactory<T> factory) {

components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormSerializationWriter.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,11 @@ public void writePeriodValue(@Nullable final String key, @Nullable final Period
111111
writeStringValue(key, value.toString());
112112
}
113113
public <T> void writeCollectionOfPrimitiveValues(@Nullable final String key, @Nullable final Iterable<T> values) {
114-
throw new RuntimeException("collections serialization is not supported with form encoding");
114+
if(values != null) {
115+
for (final T t : values) {
116+
this.writeAnyValue(key, t);
117+
}
118+
}
115119
}
116120
public <T extends Parsable> void writeCollectionOfObjectValues(@Nullable final String key, @Nullable final Iterable<T> values) {
117121
throw new RuntimeException("collections serialization is not supported with form encoding");

components/serialization/form/src/test/java/com/microsoft/kiota/serialization/FormSerializationWriterTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.time.OffsetDateTime;
1313
import java.time.Period;
1414
import java.util.ArrayList;
15+
import java.util.Arrays;
1516
import java.util.stream.Collectors;
1617

1718
import org.junit.jupiter.api.Test;
@@ -26,11 +27,13 @@ public void writesSampleObjectValue() throws IOException, UnsupportedEncodingExc
2627
setWorkDuration(Period.parse("P1M"));
2728
setStartWorkTime(LocalTime.of(8, 0, 0));
2829
setBirthDay(LocalDate.of(2017, 9, 4));
30+
setDeviceNames(Arrays.asList("device1","device2"));
2931
}};
3032
testEntity.getAdditionalData().put("mobilePhone", null);
3133
testEntity.getAdditionalData().put("jobTitle", "Author");
3234
testEntity.getAdditionalData().put("accountEnabled", false);
3335
testEntity.getAdditionalData().put("createdDateTime", OffsetDateTime.MIN);
36+
testEntity.getAdditionalData().put("otherPhones", Arrays.asList(Arrays.asList("device1","device2")));
3437
try (final var serializationWriter = new FormSerializationWriter()) {
3538
serializationWriter.writeObjectValue(null, testEntity);
3639
try(final var content = serializationWriter.getSerializedContent()) {
@@ -40,9 +43,11 @@ public void writesSampleObjectValue() throws IOException, UnsupportedEncodingExc
4043
"birthDay=2017-09-04&" + // Serializes dates
4144
"workDuration=P1M&"+ // Serializes timespans
4245
"startWorkTime=08%3A00%3A00&" + //Serializes times
46+
"deviceNames=device1&deviceNames=device2&"+
4347
"mobilePhone=null&" + // Serializes null values
4448
"jobTitle=Author&" +
4549
"createdDateTime=-999999999-01-01T00%3A00%3A00%2B18%3A00&" +
50+
"otherPhones=device1&otherPhones=device2&" +
4651
"accountEnabled=false";
4752
assertEquals(expectedString, result);
4853
}

components/serialization/form/src/test/java/com/microsoft/kiota/serialization/ParseNodeTests.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import java.time.LocalTime;
1010
import java.time.Period;
11+
import java.util.List;
12+
import java.util.UUID;
1113

1214
import org.junit.jupiter.api.Test;
1315

@@ -30,6 +32,8 @@ public class ParseNodeTests {
3032
"endWorkTime=17:00:00&" +
3133
"userPrincipalName=MeganB@M365x214355.onmicrosoft.com&" +
3234
"birthDay=2017-09-04&" +
35+
"deviceNames=device1&deviceNames=device2&"+ //collection property
36+
"otherPhones=123456789&otherPhones=987654321&" + //collection property for additionalData
3337
"id=48d31887-5fad-4d73-a9f5-3c356e68a038";
3438
@Test
3539
public void getsEntityValueFromForm() {
@@ -39,6 +43,9 @@ public void getsEntityValueFromForm() {
3943
assertNull(entity.getOfficeLocation());
4044
assertTrue(entity.getAdditionalData().containsKey("jobTitle"));
4145
assertTrue(entity.getAdditionalData().containsKey("mobilePhone"));
46+
assertTrue(entity.getAdditionalData().containsKey("mobilePhone"));
47+
assertEquals(2, entity.getDeviceNames().size());
48+
assertEquals("true", entity.getAdditionalData().get("accountEnabled"));
4249
assertEquals("Auditor", entity.getAdditionalData().get("jobTitle"));
4350
assertEquals("48d31887-5fad-4d73-a9f5-3c356e68a038", entity.getId());
4451
assertEquals(Period.parse("P1M"), entity.getWorkDuration());
@@ -57,4 +64,28 @@ public void returnsDefaultIfChildNodeDoesNotExist() {
5764
final ParseNode childNode = parseNode.getChildNode("doesNotExist");
5865
assertNull(childNode);
5966
}
67+
68+
@Test
69+
public void getCollectionOfBooleanPrimitiveValuesFromForm()
70+
{
71+
final String TestFormData = "bools=true&" +
72+
"bools=false";
73+
final ParseNode numberNode = new FormParseNode(TestFormData).getChildNode("bools");
74+
final List<Boolean> numberCollection = numberNode.getCollectionOfPrimitiveValues(Boolean.class);
75+
assertNotNull(numberCollection);
76+
assertEquals(2, numberCollection.size());
77+
assertEquals(true, numberCollection.get(0));
78+
}
79+
80+
@Test
81+
public void getCollectionOfGuidPrimitiveValuesFromForm()
82+
{
83+
final String TestFormData = "ids=48d31887-5fad-4d73-a9f5-3c356e68a038&" +
84+
"ids=48d31887-5fad-4d73-a9f5-3c356e68a038";
85+
final ParseNode numberNode = new FormParseNode(TestFormData).getChildNode("ids");
86+
var numberCollection = numberNode.getCollectionOfPrimitiveValues(UUID.class);
87+
assertNotNull(numberCollection);
88+
assertEquals(2, numberCollection.size());
89+
assertEquals(UUID.fromString("48d31887-5fad-4d73-a9f5-3c356e68a038"), numberCollection.get(0));
90+
}
6091
}

components/serialization/form/src/test/java/com/microsoft/kiota/serialization/mocks/TestEntity.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import com.microsoft.kiota.serialization.ParseNode;
44
import com.microsoft.kiota.serialization.SerializationWriter;
55

6-
import java.util.HashMap;
7-
import java.util.Map;
8-
import java.util.Objects;
6+
import java.util.*;
97
import java.util.function.Consumer;
108
import java.time.OffsetDateTime;
119
import java.time.LocalDate;
@@ -43,6 +41,14 @@ public void setBirthDay(LocalDate value) {
4341
this._birthDay = value;
4442
}
4543

44+
private List<String> _deviceNames;
45+
public List<String> getDeviceNames() {
46+
return _deviceNames;
47+
}
48+
49+
public void setDeviceNames(List<String> value) {
50+
this._deviceNames = new ArrayList<String>(value);
51+
}
4652
private Period _workDuration;
4753
public Period getWorkDuration() {
4854
return _workDuration;
@@ -105,6 +111,9 @@ public Map<String, Consumer<ParseNode>> getFieldDeserializers() {
105111
put("createdDateTime", (n) -> {
106112
setCreatedDateTime(n.getOffsetDateTimeValue());
107113
});
114+
put("deviceNames", (n) -> {
115+
setDeviceNames(n.getCollectionOfPrimitiveValues(String.class));
116+
});
108117
}};
109118
}
110119

@@ -118,6 +127,7 @@ public void serialize(SerializationWriter writer) {
118127
writer.writeLocalTimeValue("startWorkTime", getStartWorkTime());
119128
writer.writeLocalTimeValue("endWorkTime", getEndWorkTime());
120129
writer.writeOffsetDateTimeValue("createdDateTime", getCreatedDateTime());
130+
writer.writeCollectionOfPrimitiveValues("deviceNames", getDeviceNames());
121131
writer.writeAdditionalData(getAdditionalData());
122132
}
123133

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ org.gradle.caching=true
2525

2626
mavenGroupId = com.microsoft.kiota
2727
mavenMajorVersion = 0
28-
mavenMinorVersion = 2
29-
mavenPatchVersion = 1
28+
mavenMinorVersion = 3
29+
mavenPatchVersion = 0
3030
mavenArtifactSuffix =
3131

3232
#These values are used to run functional tests

0 commit comments

Comments
 (0)