Skip to content

Commit c916d51

Browse files
author
Yaniv Inbar
committed
1 parent 68b9bc2 commit c916d51

File tree

7 files changed

+84
-21
lines changed

7 files changed

+84
-21
lines changed

google-http-client-test/src/main/java/com/google/api/client/testing/json/AbstractJsonFactoryTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,4 +1366,32 @@ public void testJsonHttpContent_wrapped() throws Exception {
13661366
content.writeTo(out);
13671367
assertEquals(SIMPLE_WRAPPED, out.toString("UTF-8"));
13681368
}
1369+
1370+
public static class V {
1371+
@Key
1372+
Void v;
1373+
@Key
1374+
String s;
1375+
}
1376+
1377+
public void testParse_void() throws Exception {
1378+
subtestParse_void(null);
1379+
subtestParse_void("\"a\"");
1380+
subtestParse_void("null");
1381+
subtestParse_void("true");
1382+
subtestParse_void("false");
1383+
subtestParse_void("123");
1384+
subtestParse_void("123.456");
1385+
subtestParse_void("[1]");
1386+
subtestParse_void("{\"v\":\"ignored\"}");
1387+
}
1388+
1389+
public void subtestParse_void(String value) throws Exception {
1390+
JsonFactory factory = newFactory();
1391+
String inputString = "{" + (value == null ? "" : "\"v\":" + value + ",") + "\"s\":\"svalue\"}";
1392+
V v = factory.fromString(inputString, V.class);
1393+
assertNull(v.v);
1394+
assertEquals("svalue", v.s);
1395+
assertNull(factory.fromString(inputString, Void.class));
1396+
}
13691397
}

google-http-client/src/main/java/com/google/api/client/json/JsonParser.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,11 @@ private final Object parseValue(Field fieldContext, Type valueType, ArrayList<Ty
677677
contextStringBuilder.append("]");
678678
}
679679
String contextString = contextStringBuilder.toString();
680+
// Void means skip
681+
if (valueClass == Void.class) {
682+
skipChildren();
683+
return null;
684+
}
680685
// switch on token type
681686
switch (token) {
682687
case START_ARRAY:

google-http-client/src/main/java/com/google/api/client/util/Data.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,9 @@ public static boolean isValueOfPrimitiveType(Object fieldValue) {
361361
* Parses the given string value based on the given primitive type.
362362
* <p>
363363
* Types are parsed as follows:
364+
* </p>
364365
* <ul>
366+
* <li>{@link Void}: null</li>
365367
* <li>{@code null} or is assignable from {@link String} (like {@link Object}): no parsing</li>
366368
* <li>{@code char} or {@link Character}: {@link String#charAt(int) String.charAt}(0) (requires
367369
* length to be exactly 1)</li>
@@ -381,6 +383,11 @@ public static boolean isValueOfPrimitiveType(Object fieldValue) {
381383
* Note that this may not be the right behavior for some use cases.
382384
* </p>
383385
*
386+
* <p>
387+
* Upgrade warning: in prior version 1.14 {@link Void} was not a legal input, but starting with
388+
* version 1.15 it is now supported and returns {@code null}.
389+
* </p>
390+
*
384391
* @param type primitive type or {@code null} to parse as a string
385392
* @param stringValue string value to parse or {@code null} for {@code null} result
386393
* @return parsed object or {@code null} for {@code null} input
@@ -389,6 +396,9 @@ public static boolean isValueOfPrimitiveType(Object fieldValue) {
389396
public static Object parsePrimitiveValue(Type type, String stringValue) {
390397
Class<?> primitiveClass = type instanceof Class<?> ? (Class<?>) type : null;
391398
if (type == null || primitiveClass != null) {
399+
if (primitiveClass == Void.class) {
400+
return null;
401+
}
392402
if (stringValue == null || primitiveClass == null
393403
|| primitiveClass.isAssignableFrom(String.class)) {
394404
return stringValue;

google-http-client/src/main/java/com/google/api/client/xml/Xml.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ public boolean stopBeforeStartTag(String namespace, String localName) {
185185

186186
/**
187187
* Returns whether to stop parsing when reaching the end tag of an XML element after it has been
188-
* processed. Only called if the element is actually being processed. By default, returns {@code
189-
* false}, but subclasses may override.
188+
* processed. Only called if the element is actually being processed. By default, returns
189+
* {@code false}, but subclasses may override.
190190
*
191191
* @param namespace XML element's namespace URI
192192
* @param localName XML element's local name
@@ -277,6 +277,7 @@ private static boolean parseElementInternal(XmlPullParser parser,
277277
Field field;
278278
ArrayValueMap arrayValueMap = new ArrayValueMap(destination);
279279
boolean isStopped = false;
280+
// TODO(yanivi): support Void type as "ignore" element/attribute
280281
main: while (true) {
281282
int event = parser.next();
282283
switch (event) {
@@ -416,9 +417,8 @@ private static boolean parseElementInternal(XmlPullParser parser,
416417
// TODO(yanivi): some duplicate code here; isolate into reusable methods
417418
FieldInfo fieldInfo = FieldInfo.of(field);
418419
Object elementValue = null;
419-
Type subFieldType =
420-
isArray ? Types.getArrayComponentType(fieldType) : Types.getIterableParameter(
421-
fieldType);
420+
Type subFieldType = isArray
421+
? Types.getArrayComponentType(fieldType) : Types.getIterableParameter(fieldType);
422422
Class<?> rawArrayComponentType =
423423
Types.getRawArrayComponentType(context, subFieldType);
424424
subFieldType = Data.resolveWildcardTypeOrTypeVariable(context, subFieldType);
@@ -436,9 +436,9 @@ private static boolean parseElementInternal(XmlPullParser parser,
436436
if (subFieldType != null) {
437437
context.add(subFieldType);
438438
}
439-
Type subValueType =
440-
subFieldType != null && Map.class.isAssignableFrom(subFieldClass)
441-
? Types.getMapValueParameter(subFieldType) : null;
439+
Type subValueType = subFieldType != null
440+
&& Map.class.isAssignableFrom(subFieldClass) ? Types.getMapValueParameter(
441+
subFieldType) : null;
442442
subValueType = Data.resolveWildcardTypeOrTypeVariable(context, subValueType);
443443
isStopped = parseElementInternal(parser,
444444
context,

google-http-client/src/test/java/com/google/api/client/http/HttpHeadersTest.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,8 @@ public static class SlugHeaders extends HttpHeaders {
234234
}
235235

236236
public void testParseAge() throws Exception {
237-
MockLowLevelHttpResponse httpResponse = new MockLowLevelHttpResponse()
238-
.setHeaderNames(Arrays.asList("Age"))
239-
.setHeaderValues(Arrays.asList("3456"));
237+
MockLowLevelHttpResponse httpResponse = new MockLowLevelHttpResponse().setHeaderNames(
238+
Arrays.asList("Age")).setHeaderValues(Arrays.asList("3456"));
240239

241240
HttpHeaders httpHeaders = new HttpHeaders();
242241
httpHeaders.fromHttpResponse(httpResponse, null);
@@ -286,4 +285,20 @@ public void testFromHttpResponse_clearOldValue() throws Exception {
286285
.setHeaderValues(Arrays.asList("newvalue")), null);
287286
assertEquals(Arrays.asList("newvalue"), headers.get("Foo"));
288287
}
288+
289+
public static class V extends HttpHeaders {
290+
@Key
291+
Void v;
292+
@Key
293+
String s;
294+
}
295+
296+
public void testFromHttpResponse_void(String value) throws Exception {
297+
MockLowLevelHttpResponse httpResponse = new MockLowLevelHttpResponse().setHeaderNames(
298+
Arrays.asList("v", "v", "s")).setHeaderValues(Arrays.asList("ignore", "ignore2", "svalue"));
299+
V v = new V();
300+
v.fromHttpResponse(httpResponse, null);
301+
assertNull(v.v);
302+
assertEquals("svalue", v.s);
303+
}
289304
}

google-http-client/src/test/java/com/google/api/client/http/UrlEncodedParserTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public UrlEncodedParserTest(String name) {
4444
}
4545

4646
public static class Simple {
47+
48+
@Key
49+
Void v;
50+
4751
@Key
4852
String a;
4953

@@ -74,8 +78,7 @@ public Simple() {
7478

7579
@Override
7680
public String toString() {
77-
return Objects
78-
.toStringHelper(this)
81+
return Objects.toStringHelper(this)
7982
.add("a", a)
8083
.add("b", b)
8184
.add("c", c)
@@ -84,7 +87,6 @@ public String toString() {
8487
.add("o", o)
8588
.toString();
8689
}
87-
8890
}
8991

9092
public static class Generic extends GenericData {
@@ -111,7 +113,8 @@ public Generic set(String fieldName, Object value) {
111113

112114
public void testParse_simple() {
113115
Simple actual = new Simple();
114-
UrlEncodedParser.parse("q=1&a=x&b=y&c=z&q=2&undeclared=0&o=object&r=a1&r=a2", actual);
116+
UrlEncodedParser.parse(
117+
"v=ignore&v=ignore2&q=1&a=x&b=y&c=z&q=2&undeclared=0&o=object&r=a1&r=a2", actual);
115118
Simple expected = new Simple();
116119
expected.a = "x";
117120
expected.b = "y";
@@ -120,6 +123,7 @@ public void testParse_simple() {
120123
expected.r = new String[] {"a1", "a2"};
121124
expected.o = new ArrayList<String>(Arrays.asList("object"));
122125
assertEquals(expected, actual);
126+
assertNull(expected.v);
123127
}
124128

125129
public void testParse_generic() {

google-http-client/src/test/java/com/google/api/client/util/DataTest.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,11 @@ public void testParsePrimitiveValue() {
212212
assertEquals(new Double(Double.MAX_VALUE),
213213
Data.parsePrimitiveValue(double.class, String.valueOf(Double.MAX_VALUE)));
214214
BigInteger bigint = BigInteger.valueOf(Long.MAX_VALUE);
215-
assertEquals(bigint,
216-
Data.parsePrimitiveValue(BigInteger.class, String.valueOf(Long.MAX_VALUE)));
215+
assertEquals(
216+
bigint, Data.parsePrimitiveValue(BigInteger.class, String.valueOf(Long.MAX_VALUE)));
217217
BigDecimal bigdec = BigDecimal.valueOf(Double.MAX_VALUE);
218-
assertEquals(bigdec,
219-
Data.parsePrimitiveValue(BigDecimal.class, String.valueOf(Double.MAX_VALUE)));
218+
assertEquals(
219+
bigdec, Data.parsePrimitiveValue(BigDecimal.class, String.valueOf(Double.MAX_VALUE)));
220220
DateTime now = new DateTime(new Date());
221221
assertEquals(now, Data.parsePrimitiveValue(DateTime.class, now.toStringRfc3339()));
222222
try {
@@ -225,6 +225,7 @@ public void testParsePrimitiveValue() {
225225
} catch (IllegalArgumentException e) {
226226
// expected
227227
}
228+
assertNull(Data.parsePrimitiveValue(Void.class, "abc"));
228229
}
229230

230231
static class Resolve<X, T extends Number> {
@@ -278,8 +279,8 @@ public void testResolveWildcardTypeOrTypeVariable() throws Exception {
278279
Object.class, resolveWildcardTypeOrTypeVariable(new Object().getClass(), xTypeVar));
279280
assertEquals(Boolean.class, Types.getArrayComponentType(
280281
resolveWildcardTypeOrTypeVariable(new ArrayResolve().getClass(), xTypeVar)));
281-
assertEquals(Collection.class,
282-
Types.getRawClass((ParameterizedType) resolveWildcardTypeOrTypeVariable(
282+
assertEquals(
283+
Collection.class, Types.getRawClass((ParameterizedType) resolveWildcardTypeOrTypeVariable(
283284
new ParameterizedResolve().getClass(), xTypeVar)));
284285
assertEquals(Number.class, resolveWildcardTypeOrTypeVariable(
285286
new MedXResolve<Integer, Integer>().getClass(), xTypeVar));

0 commit comments

Comments
 (0)