]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 2008 Google Inc. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | package com.google.gson; | |
18 | ||
19 | import java.lang.reflect.Field; | |
20 | ||
21 | /** | |
22 | * An enumeration that defines a few standard naming conventions for JSON field names. | |
23 | * This enumeration should be used in conjunction with {@link com.google.gson.GsonBuilder} | |
24 | * to configure a {@link com.google.gson.Gson} instance to properly translate Java field | |
25 | * names into the desired JSON field names. | |
26 | * | |
27 | * @author Inderjeet Singh | |
28 | * @author Joel Leitch | |
29 | */ | |
30 | public enum FieldNamingPolicy implements FieldNamingStrategy { | |
31 | ||
32 | /** | |
33 | * Using this naming policy with Gson will ensure that the field name is | |
34 | * unchanged. | |
35 | */ | |
36 | IDENTITY() { | |
37 | public String translateName(Field f) { | |
38 | return f.getName(); | |
39 | } | |
40 | }, | |
41 | ||
42 | /** | |
43 | * Using this naming policy with Gson will ensure that the first "letter" of the Java | |
44 | * field name is capitalized when serialized to its JSON form. | |
45 | * | |
46 | * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p> | |
47 | * <ul> | |
48 | * <li>someFieldName ---> SomeFieldName</li> | |
49 | * <li>_someFieldName ---> _SomeFieldName</li> | |
50 | * </ul> | |
51 | */ | |
52 | UPPER_CAMEL_CASE() { | |
53 | public String translateName(Field f) { | |
54 | return upperCaseFirstLetter(f.getName()); | |
55 | } | |
56 | }, | |
57 | ||
58 | /** | |
59 | * Using this naming policy with Gson will ensure that the first "letter" of the Java | |
60 | * field name is capitalized when serialized to its JSON form and the words will be | |
61 | * separated by a space. | |
62 | * | |
63 | * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p> | |
64 | * <ul> | |
65 | * <li>someFieldName ---> Some Field Name</li> | |
66 | * <li>_someFieldName ---> _Some Field Name</li> | |
67 | * </ul> | |
68 | * | |
69 | * @since 1.4 | |
70 | */ | |
71 | UPPER_CAMEL_CASE_WITH_SPACES() { | |
72 | public String translateName(Field f) { | |
73 | return upperCaseFirstLetter(separateCamelCase(f.getName(), " ")); | |
74 | } | |
75 | }, | |
76 | ||
77 | /** | |
78 | * Using this naming policy with Gson will modify the Java Field name from its camel cased | |
79 | * form to a lower case field name where each word is separated by an underscore (_). | |
80 | * | |
81 | * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p> | |
82 | * <ul> | |
83 | * <li>someFieldName ---> some_field_name</li> | |
84 | * <li>_someFieldName ---> _some_field_name</li> | |
85 | * <li>aStringField ---> a_string_field</li> | |
86 | * <li>aURL ---> a_u_r_l</li> | |
87 | * </ul> | |
88 | */ | |
89 | LOWER_CASE_WITH_UNDERSCORES() { | |
90 | public String translateName(Field f) { | |
91 | return separateCamelCase(f.getName(), "_").toLowerCase(); | |
92 | } | |
93 | }, | |
94 | ||
95 | /** | |
96 | * Using this naming policy with Gson will modify the Java Field name from its camel cased | |
97 | * form to a lower case field name where each word is separated by a dash (-). | |
98 | * | |
99 | * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p> | |
100 | * <ul> | |
101 | * <li>someFieldName ---> some-field-name</li> | |
102 | * <li>_someFieldName ---> _some-field-name</li> | |
103 | * <li>aStringField ---> a-string-field</li> | |
104 | * <li>aURL ---> a-u-r-l</li> | |
105 | * </ul> | |
106 | * Using dashes in JavaScript is not recommended since dash is also used for a minus sign in | |
107 | * expressions. This requires that a field named with dashes is always accessed as a quoted | |
108 | * property like {@code myobject['my-field']}. Accessing it as an object field | |
109 | * {@code myobject.my-field} will result in an unintended javascript expression. | |
110 | * @since 1.4 | |
111 | */ | |
112 | LOWER_CASE_WITH_DASHES() { | |
113 | public String translateName(Field f) { | |
114 | return separateCamelCase(f.getName(), "-").toLowerCase(); | |
115 | } | |
116 | }; | |
117 | ||
118 | /** | |
119 | * Converts the field name that uses camel-case define word separation into | |
120 | * separate words that are separated by the provided {@code separatorString}. | |
121 | */ | |
122 | private static String separateCamelCase(String name, String separator) { | |
123 | StringBuilder translation = new StringBuilder(); | |
124 | for (int i = 0; i < name.length(); i++) { | |
125 | char character = name.charAt(i); | |
126 | if (Character.isUpperCase(character) && translation.length() != 0) { | |
127 | translation.append(separator); | |
128 | } | |
129 | translation.append(character); | |
130 | } | |
131 | return translation.toString(); | |
132 | } | |
133 | ||
134 | /** | |
135 | * Ensures the JSON field names begins with an upper case letter. | |
136 | */ | |
137 | private static String upperCaseFirstLetter(String name) { | |
138 | StringBuilder fieldNameBuilder = new StringBuilder(); | |
139 | int index = 0; | |
140 | char firstCharacter = name.charAt(index); | |
141 | ||
142 | while (index < name.length() - 1) { | |
143 | if (Character.isLetter(firstCharacter)) { | |
144 | break; | |
145 | } | |
146 | ||
147 | fieldNameBuilder.append(firstCharacter); | |
148 | firstCharacter = name.charAt(++index); | |
149 | } | |
150 | ||
151 | if (index == name.length()) { | |
152 | return fieldNameBuilder.toString(); | |
153 | } | |
154 | ||
155 | if (!Character.isUpperCase(firstCharacter)) { | |
156 | String modifiedTarget = modifyString(Character.toUpperCase(firstCharacter), name, ++index); | |
157 | return fieldNameBuilder.append(modifiedTarget).toString(); | |
158 | } else { | |
159 | return name; | |
160 | } | |
161 | } | |
162 | ||
163 | private static String modifyString(char firstCharacter, String srcString, int indexOfSubstring) { | |
164 | return (indexOfSubstring < srcString.length()) | |
165 | ? firstCharacter + srcString.substring(indexOfSubstring) | |
166 | : String.valueOf(firstCharacter); | |
167 | } | |
168 | } |