Skip to content

Commit e440a11

Browse files
committed
json-iterator#57 inherited setter is not duplicate
1 parent 7082793 commit e440a11

3 files changed

Lines changed: 69 additions & 29 deletions

File tree

src/main/java/com/jsoniter/spi/Binding.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,14 @@ public boolean equals(Object o) {
106106
Binding binding = (Binding) o;
107107

108108
if (clazz != null ? !clazz.equals(binding.clazz) : binding.clazz != null) return false;
109+
if (method != null ? !method.equals(binding.method) : binding.method != null) return false;
109110
return name != null ? name.equals(binding.name) : binding.name == null;
110111
}
111112

112113
@Override
113114
public int hashCode() {
114115
int result = clazz != null ? clazz.hashCode() : 0;
116+
result = 31 * result + (method != null ? method.hashCode() : 0);
115117
result = 31 * result + (name != null ? name.hashCode() : 0);
116118
return result;
117119
}

src/main/java/com/jsoniter/spi/JsoniterSpi.java

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -187,27 +187,57 @@ public static ClassDescriptor getEncodingClassDescriptor(Class clazz, boolean in
187187
private static void decodingDeduplicate(ClassDescriptor desc) {
188188
HashMap<String, Binding> byName = new HashMap<String, Binding>();
189189
for (Binding field : desc.fields) {
190-
if (byName.containsKey(field.name)) {
191-
throw new JsonException("field name conflict: " + field.name);
190+
for (String fromName : field.fromNames) {
191+
if (byName.containsKey(fromName)) {
192+
throw new JsonException("field decode from same name: " + fromName);
193+
}
194+
byName.put(fromName, field);
192195
}
193-
byName.put(field.name, field);
194196
}
195-
for (Binding setter : desc.setters) {
196-
Binding existing = byName.get(setter.name);
197-
if (existing == null) {
198-
byName.put(setter.name, setter);
199-
continue;
200-
}
201-
if (desc.fields.remove(existing)) {
202-
continue;
197+
ArrayList<Binding> iteratingSetters = new ArrayList<Binding>(desc.setters);
198+
Collections.reverse(iteratingSetters);
199+
for (Binding setter : iteratingSetters) {
200+
for (String fromName : setter.fromNames) {
201+
Binding existing = byName.get(fromName);
202+
if (existing == null) {
203+
byName.put(fromName, setter);
204+
continue;
205+
}
206+
if (desc.fields.remove(existing)) {
207+
continue;
208+
}
209+
if (existing.method != null && existing.method.getName().equals(setter.method.getName())) {
210+
// inherited interface setter
211+
// iterate in reverse order, so that the setter from child class will be kept
212+
desc.setters.remove(existing);
213+
continue;
214+
}
215+
throw new JsonException("setter decode from same name: " + fromName);
203216
}
204-
throw new JsonException("setter name conflict: " + setter.name);
205217
}
206218
for (WrapperDescriptor wrapper : desc.wrappers) {
207219
for (Binding param : wrapper.parameters) {
208-
Binding existing = byName.get(param.name);
220+
for (String fromName : param.fromNames) {
221+
Binding existing = byName.get(fromName);
222+
if (existing == null) {
223+
byName.put(fromName, param);
224+
continue;
225+
}
226+
if (desc.fields.remove(existing)) {
227+
continue;
228+
}
229+
if (desc.setters.remove(existing)) {
230+
continue;
231+
}
232+
throw new JsonException("wrapper parameter decode from same name: " + fromName);
233+
}
234+
}
235+
}
236+
for (Binding param : desc.ctor.parameters) {
237+
for (String fromName : param.fromNames) {
238+
Binding existing = byName.get(fromName);
209239
if (existing == null) {
210-
byName.put(param.name, param);
240+
byName.put(fromName, param);
211241
continue;
212242
}
213243
if (desc.fields.remove(existing)) {
@@ -216,22 +246,8 @@ private static void decodingDeduplicate(ClassDescriptor desc) {
216246
if (desc.setters.remove(existing)) {
217247
continue;
218248
}
219-
throw new JsonException("wrapper parameter name conflict: " + param.name);
220-
}
221-
}
222-
for (Binding param : desc.ctor.parameters) {
223-
Binding existing = byName.get(param.name);
224-
if (existing == null) {
225-
byName.put(param.name, param);
226-
continue;
227-
}
228-
if (desc.fields.remove(existing)) {
229-
continue;
230-
}
231-
if (desc.setters.remove(existing)) {
232-
continue;
249+
throw new JsonException("ctor parameter decode from same name: " + fromName);
233250
}
234-
throw new JsonException("ctor parameter name conflict: " + param.name);
235251
}
236252
}
237253

@@ -257,6 +273,7 @@ private static void encodingDeduplicate(ClassDescriptor desc) {
257273
continue;
258274
}
259275
if (existing.method != null && existing.method.getName().equals(getter.method.getName())) {
276+
// inherited interface getter
260277
desc.getters.remove(getter);
261278
continue;
262279
}

src/test/java/com/jsoniter/TestAnnotation.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,25 @@ public void test_name_conflict() throws IOException {
270270
JsonIterator iter = JsonIterator.parse("{}");
271271
assertNotNull(iter.read(TestObject17.class));
272272
}
273+
274+
public interface TestObject18Interface<A> {
275+
void setHello(A val);
276+
}
277+
278+
public static class TestObject18 implements TestObject18Interface<Integer> {
279+
280+
public int _val;
281+
282+
@Override
283+
public void setHello(Integer val) {
284+
_val = val;
285+
}
286+
}
287+
288+
public void test_inherited_setter_is_not_duplicate() throws IOException {
289+
JsonIterator iter = JsonIterator.parse("{\"hello\":1}");
290+
TestObject18 obj = iter.read(TestObject18.class);
291+
assertNotNull(obj);
292+
assertEquals(1, obj._val);
293+
}
273294
}

0 commit comments

Comments
 (0)