amenijemai / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

In Turkish locale, FieldNamingPolicy that lowercases field names causes problems with I and dot-less i #541

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Use a Java environment running in Turkish language/locale. (Can specify with 
a commandline flag: -Duser.language=tr -Duser.region=TR)
2. Create a Gson object with FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES (see 
example code).
3. Create a serializable object / class with camel-cased capital I, e.g. 
objectId. (see example code).
4. Serialize this object via Gson.toJson(), (see example code).

Expected vs Actual:
We expect camel-cased fieldnames such as objectId to be serialized as 
object_id. But in Turkish locale it comes out as: object_ıd.

Version & Environment:
Gson 2.2.1 on Android. Repro steps tested in Java 6 environment.

Suggested fix:
In gson/src/main/java/com/google/gson/FieldNamingPolicy.java, two enum members:
LOWER_CASE_WITH_UNDERSCORES
LOWER_CASE_WITH_DASHES
the String.toLower() method should be changed to String.toLower(Locale.ROOT), 
so that fieldnames/JSON keys are treated as internal strings (not user facing 
strings that need to respect the Locale's upper/lowercasing conventions).

Example code:
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Test {
    private static Gson getGson() {
        return new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .create();
    }

    public static void main(String[] args) {
        final Gson g = getGson();

        final Struct testObject = new Struct();
        testObject.someId = 1;
        testObject.someInteger = 2;
        testObject.someInfo = "3";

        System.out.println(g.toJson(testObject));
    }
}

public class Struct {
    int someId;
    int someInteger;
    String someInfo;
}

Original issue reported on code.google.com by j...@thumbsuplabs.com on 30 Oct 2013 at 11:11

GoogleCodeExporter commented 9 years ago
The solution for this is easy.  On the latest svn pull, change line 91 of 
FIeldNamingPolicy from: return separateCamelCase(f.getName(), 
"_").toLowerCase(); to return separateCamelCase(f.getName(), 
"_").toLowerCase(Locale.ROOT);

There are of course other toLowerCase/toUpperCase calls in that class that 
would need to be changed as well.  Unless the Locale.toLowerCase() using 
default locale is a quirk specific to Android, this is a definite bug that 
needs to be fixed.  Is there somewhere I can submit a patch?

Original comment by alex.put...@starmakerinteractive.com on 11 Feb 2014 at 9:45

GoogleCodeExporter commented 9 years ago
Oh wow Oct 2013.  Still, this bug persists in gson 2.2.4.

Original comment by alex.put...@starmakerinteractive.com on 11 Feb 2014 at 9:46

GoogleCodeExporter commented 9 years ago
If anyone else is having this issue, you can implement your own 
FieldNamingStrategy to work around it.  

public class LocaleAgnosticFieldNamingStrategy implements FieldNamingStrategy {
    @Override
    public String translateName(Field field) {
        return separateCamelCase(field.getName(), "_").toLowerCase(Locale.ROOT);
    }

    /**
     * Converts the field name that uses camel-case define word separation into
     * separate words that are separated by the provided {@code separatorString}.
     */
    private static String separateCamelCase(String name, String separator) {
        StringBuilder translation = new StringBuilder();
        for (int i = 0; i < name.length(); i++) {
            char character = name.charAt(i);
            if (Character.isUpperCase(character) && translation.length() != 0) {
                translation.append(separator);
            }
            translation.append(character);
        }
        return translation.toString();
    }
}

Original comment by alex.put...@starmakerinteractive.com on 11 Feb 2014 at 9:48

GoogleCodeExporter commented 9 years ago
Actually, here's a diff for the fix.

Original comment by alex.put...@starmakerinteractive.com on 12 Feb 2014 at 2:14

Attachments: