Skip to content

Commit c833dd4

Browse files
committed
[Issue 17] When a subclass with a field annotated with @key hides a superclass field annotated with @key, prefer the definition from the subclass.
http://codereview.appspot.com/6312057/
1 parent d6ce61b commit c833dd4

File tree

3 files changed

+86
-8
lines changed

3 files changed

+86
-8
lines changed

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,6 @@ public int compare(String s0, String s1) {
169169
return s0 == s1 ? 0 : s0 == null ? -1 : s1 == null ? 1 : s0.compareTo(s1);
170170
}
171171
});
172-
// inherit from super class
173-
Class<?> superClass = srcClass.getSuperclass();
174-
if (superClass != null) {
175-
ClassInfo superClassInfo = ClassInfo.of(superClass, ignoreCase);
176-
nameToFieldInfoMap.putAll(superClassInfo.nameToFieldInfoMap);
177-
nameSet.addAll(superClassInfo.names);
178-
}
179172
// iterate over declared fields
180173
for (Field field : srcClass.getDeclaredFields()) {
181174
FieldInfo fieldInfo = FieldInfo.of(field);
@@ -196,6 +189,18 @@ public int compare(String s0, String s1) {
196189
nameToFieldInfoMap.put(fieldName, fieldInfo);
197190
nameSet.add(fieldName);
198191
}
192+
// inherit from super class and add only fields not already in nameToFieldInfoMap
193+
Class<?> superClass = srcClass.getSuperclass();
194+
if (superClass != null) {
195+
ClassInfo superClassInfo = ClassInfo.of(superClass, ignoreCase);
196+
nameSet.addAll(superClassInfo.names);
197+
for (Map.Entry<String, FieldInfo> e : superClassInfo.nameToFieldInfoMap.entrySet()) {
198+
String name = e.getKey();
199+
if (!nameToFieldInfoMap.containsKey(name)) {
200+
nameToFieldInfoMap.put(name, e.getValue());
201+
}
202+
}
203+
}
199204
names = nameSet.isEmpty() ? Collections.<String>emptyList() : Collections.unmodifiableList(
200205
new ArrayList<String>(nameSet));
201206
}

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@
1515
package com.google.api.client.http;
1616

1717
import com.google.api.client.http.LogContentTest.Recorder;
18+
import com.google.api.client.json.JsonObjectParser;
19+
import com.google.api.client.json.JsonString;
20+
import com.google.api.client.json.jackson.JacksonFactory;
1821
import com.google.api.client.testing.http.HttpTesting;
1922
import com.google.api.client.testing.http.MockHttpTransport;
2023
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
2124
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
25+
import com.google.api.client.util.GenericData;
2226
import com.google.api.client.util.Key;
2327
import com.google.api.client.util.StringUtils;
2428

@@ -389,4 +393,63 @@ public LowLevelHttpResponse execute() throws IOException {
389393
response.parseAsString();
390394
recorder.assertMessages(expectedMessages);
391395
}
396+
397+
public static class A extends GenericData {
398+
@Key
399+
String foo;
400+
401+
public A() {
402+
super();
403+
}
404+
}
405+
406+
public static class B extends A {
407+
@SuppressWarnings("hiding")
408+
@Key
409+
@JsonString
410+
Integer foo;
411+
412+
public B() {
413+
super();
414+
}
415+
}
416+
417+
public static class C extends B {
418+
@SuppressWarnings("hiding")
419+
@Key
420+
String foo;
421+
422+
public C() {
423+
super();
424+
}
425+
}
426+
427+
public void testParseWithOverridenKey() throws IOException {
428+
GenericData bData = new B();
429+
bData.set("foo", 1);
430+
GenericData cData = new C();
431+
cData.set("foo", "1");
432+
433+
HttpTransport transport = new MockHttpTransport() {
434+
@Override
435+
public LowLevelHttpRequest buildGetRequest(String url) throws IOException {
436+
return new MockLowLevelHttpRequest() {
437+
@Override
438+
public LowLevelHttpResponse execute() throws IOException {
439+
MockLowLevelHttpResponse result = new MockLowLevelHttpResponse();
440+
result.setContentType("application/json; charset=UTF-8");
441+
result.setContent("{\"foo\": \"1\"}");
442+
return result;
443+
}
444+
};
445+
}
446+
};
447+
HttpRequest request =
448+
transport.createRequestFactory().buildGetRequest(HttpTesting.SIMPLE_GENERIC_URL);
449+
request.setParser(new JsonObjectParser(new JacksonFactory()));
450+
HttpResponse response = request.execute();
451+
assertEquals(bData, response.parseAs(B.class));
452+
response = request.execute();
453+
assertEquals(cData, response.parseAs(C.class));
454+
}
392455
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ public class C extends B {
7171
String abc2;
7272
}
7373

74+
public class A1 {
75+
@Key
76+
String foo;
77+
@Key("foo")
78+
String foo2;
79+
}
80+
7481
public void testNames() {
7582
assertEquals(ImmutableList.of("AbC", "b", "oc"), ClassInfo.of(A.class).names);
7683
assertEquals(ImmutableList.of("AbC", "b", "e", "oc"), ClassInfo.of(B.class).names);
@@ -88,11 +95,14 @@ public void testNames_enum() {
8895

8996
public void testOf() {
9097
try {
91-
ClassInfo.of(C.class, true);
98+
ClassInfo.of(A1.class, true);
9299
fail("expected " + IllegalArgumentException.class);
93100
} catch (IllegalArgumentException e) {
94101
// expected
95102
}
103+
104+
ClassInfo.of(C.class, true);
105+
96106
try {
97107
ClassInfo.of(E.class, true);
98108
fail("expected " + IllegalArgumentException.class);

0 commit comments

Comments
 (0)