diff --git a/google-http-client/src/main/java/com/google/api/client/util/FieldInfo.java b/google-http-client/src/main/java/com/google/api/client/util/FieldInfo.java index 3830a8664..36d0dc9dc 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/FieldInfo.java +++ b/google-http-client/src/main/java/com/google/api/client/util/FieldInfo.java @@ -134,12 +134,20 @@ public static FieldInfo of(Field field) { } /** Creates list of setter methods for a field only in declaring class. */ - private Method[] settersMethodForField(Field field) { + private Method[] settersMethodForField(final Field field) { List methods = new ArrayList<>(); + String fieldSetter = "set" + Ascii.toUpperCase(field.getName().substring(0, 1)); + if (field.getName().length() > 1) { + fieldSetter += field.getName().substring(1); + } for (Method method : field.getDeclaringClass().getDeclaredMethods()) { - if (Ascii.toLowerCase(method.getName()).equals("set" + Ascii.toLowerCase(field.getName())) - && method.getParameterTypes().length == 1) { - methods.add(method); + if (method.getParameterTypes().length == 1) { + // add case-sensitive matches first in the list + if (method.getName().equals(fieldSetter)) { + methods.add(0, method); + } else if (Ascii.toLowerCase(method.getName()).equals(Ascii.toLowerCase(fieldSetter))) { + methods.add(method); + } } } return methods.toArray(new Method[0]); @@ -216,15 +224,13 @@ public Object getValue(Object obj) { * value. */ public void setValue(Object obj, Object value) { - if (setters.length > 0) { - for (Method method : setters) { - if (value == null || method.getParameterTypes()[0].isAssignableFrom(value.getClass())) { - try { - method.invoke(obj, value); - return; - } catch (IllegalAccessException | InvocationTargetException e) { - // try to set field directly - } + for (Method method : setters) { + if (value == null || method.getParameterTypes()[0].isAssignableFrom(value.getClass())) { + try { + method.invoke(obj, value); + return; + } catch (IllegalAccessException | InvocationTargetException e) { + // try to set field directly } } } diff --git a/google-http-client/src/test/java/com/google/api/client/util/FieldInfoTest.java b/google-http-client/src/test/java/com/google/api/client/util/FieldInfoTest.java index c000a90dd..0cd1c17de 100644 --- a/google-http-client/src/test/java/com/google/api/client/util/FieldInfoTest.java +++ b/google-http-client/src/test/java/com/google/api/client/util/FieldInfoTest.java @@ -14,6 +14,7 @@ package com.google.api.client.util; +import com.google.api.client.json.GenericJson; import junit.framework.TestCase; /** @@ -49,4 +50,36 @@ public void testEnumValue() { assertEquals(E.OTHER_VALUE, FieldInfo.of(E.OTHER_VALUE).enumValue()); assertEquals(E.NULL, FieldInfo.of(E.NULL).enumValue()); } + + public static final class Data extends GenericJson { + @Key String passcode; + @Key String passCode; + + public Data setPasscode(String passcode) { + this.passcode = passcode; + return this; + } + + public Data setPassCode(String passCode) { + this.passCode = passCode; + return this; + } + } + + public void testSetValueCaseSensitivityPriority() { + Data data = new Data(); + data.setPasscode("pass1"); + data.setPassCode("pass2"); + data.set("passCode", "passX"); + + assertEquals(data.passcode, "pass1"); + assertEquals(data.passCode, "passX"); + + data.setPasscode("pass1"); + data.setPassCode("pass2"); + data.set("passcode", "passX"); + + assertEquals(data.passcode, "passX"); + assertEquals(data.passCode, "pass2"); + } }