public class URLReference_Serializer implements JSONSerializer<URLReference> {
+ // setURL() -> uRL as first char becomes lower case...
+ private static final String URL_FIELD = "uRL";
+
public URLReference deserialize(Type type, JSONValue jsonValue,
ApplicationConnection connection) {
URLReference reference = GWT.create(URLReference.class);
JSONObject json = (JSONObject) jsonValue;
- if (json.containsKey("URL")) {
- JSONValue jsonURL = json.get("URL");
+ if (json.containsKey(URL_FIELD)) {
+ JSONValue jsonURL = json.get(URL_FIELD);
String URL = (String) JsonDecoder.decodeValue(
new Type(String.class.getName(), null), jsonURL, null,
connection);
return reference;
}
- public JSONValue serialize(URLReference value, ApplicationConnection connection) {
+ public JSONValue serialize(URLReference value,
+ ApplicationConnection connection) {
JSONObject json = new JSONObject();
- json.put("URL",
+ json.put(URL_FIELD,
JsonEncoder.encode(value.getURL(), true, connection));
return json;
}
* Returns the name that should be used as field name in the JSON. We strip
* "set" from the setter, keeping the result - this is easy to do on both
* server and client, avoiding some issues with cASE. E.g setZIndex()
- * becomes "ZIndex". Also ensures that both getter and setter are present,
+ * becomes "zIndex". Also ensures that both getter and setter are present,
* returning null otherwise.
*
* @param pd
if (pd.getReadMethod() == null || pd.getWriteMethod() == null) {
return null;
}
- return pd.getWriteMethod().getName().substring(3);
+ String fieldName = pd.getWriteMethod().getName().substring(3);
+ fieldName = Character.toLowerCase(fieldName.charAt(0))
+ + fieldName.substring(1);
+ return fieldName;
}
private static Object decodeObject(Type targetType,
equals = equals(fieldValue, referenceFieldValue);
}
if (!equals) {
+ if (jsonMap.has(fieldName)) {
+ throw new RuntimeException(
+ "Can't encode "
+ + value.getClass().getName()
+ + " as it has multiple fields with the name "
+ + fieldName.toLowerCase()
+ + ". This can happen if only casing distinguishes one property name from another.");
+ }
jsonMap.put(
fieldName,
encode(fieldValue, referenceFieldValue, fieldType,
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import com.google.gwt.core.client.GWT;
* bean type for which the serializer is to be generated
* @param beanSerializerTypeName
* name of the serializer class to generate
+ * @throws UnableToCompleteException
*/
private void generateClass(TreeLogger logger, GeneratorContext context,
JClassType beanType, String serializerPackageName,
- String serializerClassName) {
+ String serializerClassName) throws UnableToCompleteException {
// get print writer that receives the source code
PrintWriter printWriter = null;
printWriter = context.tryCreate(logger, serializerPackageName,
for (JMethod method : getSetters(beanType)) {
String setterName = method.getName();
- String fieldName = setterName.substring(3); // setZIndex() -> ZIndex
+ String baseName = setterName.substring(3);
+ String fieldName = getTransportFieldName(baseName); // setZIndex()
+ // -> zIndex
JType setterParameterType = method.getParameterTypes()[0];
logger.log(Type.DEBUG, "* Processing field " + fieldName + " in "
+ " = json.get(\"" + fieldName + "\");");
String fieldType;
- String getterName = "get" + fieldName;
+ String getterName = "get" + baseName;
JPrimitiveType primitiveType = setterParameterType.isPrimitive();
if (primitiveType != null) {
// This is a primitive type -> must used the boxed type
fieldType = primitiveType.getQualifiedBoxedSourceName();
if (primitiveType == JPrimitiveType.BOOLEAN) {
- getterName = "is" + fieldName;
+ getterName = "is" + baseName;
}
} else {
fieldType = setterParameterType.getQualifiedSourceName();
}
private void writeBeanSerializer(TreeLogger logger,
- SourceWriter sourceWriter, JClassType beanType) {
+ SourceWriter sourceWriter, JClassType beanType)
+ throws UnableToCompleteException {
// JSONObject json = new JSONObject();
sourceWriter.println(JSONObject.class.getName() + " json = new "
+ JSONObject.class.getName() + "();");
+ HashSet<String> usedFieldNames = new HashSet<String>();
+
for (JMethod setterMethod : getSetters(beanType)) {
String setterName = setterMethod.getName();
- String fieldName = setterName.substring(3); // setZIndex() -> ZIndex
+ String fieldName = getTransportFieldName(setterName.substring(3)); // setZIndex()
+ // -> zIndex
+ if (!usedFieldNames.add(fieldName)) {
+ logger.log(
+ TreeLogger.ERROR,
+ "Can't encode "
+ + beanType.getQualifiedSourceName()
+ + " as it has multiple fields with the name "
+ + fieldName.toLowerCase()
+ + ". This can happen if only casing distinguishes one property name from another.");
+ throw new UnableToCompleteException();
+ }
String getterName = findGetter(beanType, setterMethod);
if (getterName == null) {
}
+ private static String getTransportFieldName(String baseName) {
+ return Character.toLowerCase(baseName.charAt(0))
+ + baseName.substring(1);
+ }
+
private String findGetter(JClassType beanType, JMethod setterMethod) {
JType setterParameterType = setterMethod.getParameterTypes()[0];
String fieldName = setterMethod.getName().substring(3);