Deprecate the FieldNamingStrategy interface and replace it with FieldNamingStrategy2. This is the first step to help make it easy to cache field annotations across all instances of a class, etc.
This commit is contained in:
parent
7079799890
commit
e3af076ff2
|
@ -18,6 +18,7 @@ package com.google.gson;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the field name that uses camel-case define word separation into separate words that
|
* Converts the field name that uses camel-case define word separation into separate words that
|
||||||
|
@ -56,7 +57,8 @@ final class CamelCaseSeparatorNamingPolicy extends RecursiveFieldNamingPolicy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String translateName(String target, Type fieldType, Annotation[] annnotations) {
|
protected String translateName(String target, Type fieldType,
|
||||||
|
Collection<Annotation> annnotations) {
|
||||||
StringBuilder translation = new StringBuilder();
|
StringBuilder translation = new StringBuilder();
|
||||||
for (int i = 0; i < target.length(); i++) {
|
for (int i = 0; i < target.length(); i++) {
|
||||||
char character = target.charAt(i);
|
char character = target.charAt(i);
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.google.gson;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
package com.google.gson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception class to indicate a circular reference error.
|
* Exception class to indicate a circular reference error.
|
||||||
|
@ -33,7 +32,7 @@ final class CircularReferenceException extends RuntimeException {
|
||||||
this.offendingNode = offendingNode;
|
this.offendingNode = offendingNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IllegalStateException createDetailedException(Field offendingField) {
|
public IllegalStateException createDetailedException(FieldAttributes offendingField) {
|
||||||
StringBuilder msg = new StringBuilder(getMessage());
|
StringBuilder msg = new StringBuilder(getMessage());
|
||||||
if (offendingField != null) {
|
if (offendingField != null) {
|
||||||
msg.append("\n ").append("Offending field: ").append(offendingField.getName() + "\n");
|
msg.append("\n ").append("Offending field: ").append(offendingField.getName() + "\n");
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.google.gson;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs numerous field naming translations wrapped up as one object.
|
* Performs numerous field naming translations wrapped up as one object.
|
||||||
|
@ -36,7 +37,7 @@ abstract class CompositionFieldNamingPolicy extends RecursiveFieldNamingPolicy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String translateName(String target, Type fieldType, Annotation[] annotations) {
|
protected String translateName(String target, Type fieldType, Collection<Annotation> annotations) {
|
||||||
for (RecursiveFieldNamingPolicy policy : fieldPolicies) {
|
for (RecursiveFieldNamingPolicy policy : fieldPolicies) {
|
||||||
target = policy.translateName(target, fieldType, annotations);
|
target = policy.translateName(target, fieldType, annotations);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ package com.google.gson;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A data object that stores attributes of a field.
|
* A data object that stores attributes of a field.
|
||||||
|
@ -35,11 +38,11 @@ public final class FieldAttributes {
|
||||||
private final Class<?> declaredType;
|
private final Class<?> declaredType;
|
||||||
private final boolean isSynthetic;
|
private final boolean isSynthetic;
|
||||||
private final int modifiers;
|
private final int modifiers;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
// Fields used for lazy initialization
|
// Fields used for lazy initialization
|
||||||
private String name;
|
|
||||||
private Type genericType;
|
private Type genericType;
|
||||||
private Annotation[] annotations;
|
private Collection<Annotation> annotations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a Field Attributes object from the {@code f}.
|
* Constructs a Field Attributes object from the {@code f}.
|
||||||
|
@ -49,6 +52,7 @@ public final class FieldAttributes {
|
||||||
FieldAttributes(final Field f) {
|
FieldAttributes(final Field f) {
|
||||||
Preconditions.checkNotNull(f);
|
Preconditions.checkNotNull(f);
|
||||||
field = f;
|
field = f;
|
||||||
|
name = field.getName();
|
||||||
declaredType = f.getType();
|
declaredType = f.getType();
|
||||||
isSynthetic = f.isSynthetic();
|
isSynthetic = f.isSynthetic();
|
||||||
modifiers = field.getModifiers();
|
modifiers = field.getModifiers();
|
||||||
|
@ -58,9 +62,6 @@ public final class FieldAttributes {
|
||||||
* @return the name of the field
|
* @return the name of the field
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
if (name == null) {
|
|
||||||
name = field.getName();
|
|
||||||
}
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +116,21 @@ public final class FieldAttributes {
|
||||||
* @return the annotation instance if it is bound to the field; otherwise {@code null}
|
* @return the annotation instance if it is bound to the field; otherwise {@code null}
|
||||||
*/
|
*/
|
||||||
public <T extends Annotation> T getAnnotation(Class<T> annotation) {
|
public <T extends Annotation> T getAnnotation(Class<T> annotation) {
|
||||||
|
return getAnnotationFromArray(getAnnotations(), annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the annotations that are present on this field.
|
||||||
|
*
|
||||||
|
* @return an array of all the annotations set on the field
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
public Collection<Annotation> getAnnotations() {
|
||||||
if (annotations == null) {
|
if (annotations == null) {
|
||||||
annotations = field.getAnnotations();
|
annotations = Collections.unmodifiableCollection(
|
||||||
|
Arrays.asList(field.getAnnotations()));
|
||||||
}
|
}
|
||||||
return getAnnotationFromArray(annotations, annotation);
|
return annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,6 +147,28 @@ public final class FieldAttributes {
|
||||||
return (modifiers & modifier) != 0;
|
return (modifiers & modifier) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is exposed internally only for the removing synthetic fields from the JSON output.
|
||||||
|
*
|
||||||
|
* @return true if the field is synthetic; otherwise false
|
||||||
|
* @throws IllegalAccessException
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
*/
|
||||||
|
void set(Object instance, Object value) throws IllegalAccessException {
|
||||||
|
field.set(instance, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is exposed internally only for the removing synthetic fields from the JSON output.
|
||||||
|
*
|
||||||
|
* @return true if the field is synthetic; otherwise false
|
||||||
|
* @throws IllegalAccessException
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
*/
|
||||||
|
Object get(Object instance) throws IllegalAccessException {
|
||||||
|
return field.get(instance);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is exposed internally only for the removing synthetic fields from the JSON output.
|
* This is exposed internally only for the removing synthetic fields from the JSON output.
|
||||||
*
|
*
|
||||||
|
@ -144,9 +178,17 @@ public final class FieldAttributes {
|
||||||
return isSynthetic;
|
return isSynthetic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated remove this when {@link FieldNamingStrategy} is deleted.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
Field getFieldObject() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static <T extends Annotation> T getAnnotationFromArray(
|
private static <T extends Annotation> T getAnnotationFromArray(
|
||||||
Annotation[] annotations, Class<T> annotation) {
|
Collection<Annotation> annotations, Class<T> annotation) {
|
||||||
for (Annotation a : annotations) {
|
for (Annotation a : annotations) {
|
||||||
if (a.annotationType() == annotation) {
|
if (a.annotationType() == annotation) {
|
||||||
return (T) a;
|
return (T) a;
|
||||||
|
|
|
@ -72,13 +72,13 @@ public enum FieldNamingPolicy {
|
||||||
*/
|
*/
|
||||||
LOWER_CASE_WITH_DASHES(new LowerCamelCaseSeparatorNamingPolicy("-"));
|
LOWER_CASE_WITH_DASHES(new LowerCamelCaseSeparatorNamingPolicy("-"));
|
||||||
|
|
||||||
private final FieldNamingStrategy namingPolicy;
|
private final FieldNamingStrategy2 namingPolicy;
|
||||||
|
|
||||||
private FieldNamingPolicy(FieldNamingStrategy namingPolicy) {
|
private FieldNamingPolicy(FieldNamingStrategy2 namingPolicy) {
|
||||||
this.namingPolicy = namingPolicy;
|
this.namingPolicy = namingPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldNamingStrategy getFieldNamingPolicy() {
|
FieldNamingStrategy2 getFieldNamingPolicy() {
|
||||||
return namingPolicy;
|
return namingPolicy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,9 @@ import java.lang.reflect.Field;
|
||||||
* @author Inderjeet Singh
|
* @author Inderjeet Singh
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
* @since 1.3
|
* @since 1.3
|
||||||
|
* @deprecated use {@link FieldNamingStrategy2} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface FieldNamingStrategy {
|
public interface FieldNamingStrategy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
39
gson/src/main/java/com/google/gson/FieldNamingStrategy2.java
Normal file
39
gson/src/main/java/com/google/gson/FieldNamingStrategy2.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The new mechanism for providing custom field naming in Gson. This allows the client code
|
||||||
|
* to translate field names into a particular convention that is not supported as a normal
|
||||||
|
* Java field declaration rules. For example, Java does not support "-" characters in a
|
||||||
|
* field name.
|
||||||
|
*
|
||||||
|
* @author Inderjeet Singh
|
||||||
|
* @author Joel Leitch
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
public interface FieldNamingStrategy2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the field name into its JSON field name representation.
|
||||||
|
*
|
||||||
|
* @param f the field that is being translated
|
||||||
|
* @return the translated field name.
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public String translateName(FieldAttributes f);
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapts the old "deprecated" {@link FieldNamingStrategy} to the new {@link FieldNamingStrategy2}
|
||||||
|
* type.
|
||||||
|
*
|
||||||
|
* @author Inderjeet Singh
|
||||||
|
* @author Joel Leitch
|
||||||
|
*/
|
||||||
|
class FieldNamingStrategy2Adapter implements FieldNamingStrategy2 {
|
||||||
|
private final FieldNamingStrategy adaptee;
|
||||||
|
|
||||||
|
public FieldNamingStrategy2Adapter(FieldNamingStrategy adaptee) {
|
||||||
|
Preconditions.checkNotNull(adaptee);
|
||||||
|
this.adaptee = adaptee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String translateName(FieldAttributes f) {
|
||||||
|
return adaptee.translateName(f.getFieldObject());
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,7 +86,7 @@ public final class Gson {
|
||||||
static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
|
static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
|
||||||
new ModifierBasedExclusionStrategy(new int[] { Modifier.TRANSIENT, Modifier.STATIC });
|
new ModifierBasedExclusionStrategy(new int[] { Modifier.TRANSIENT, Modifier.STATIC });
|
||||||
static final JsonFormatter DEFAULT_JSON_FORMATTER = new JsonCompactFormatter();
|
static final JsonFormatter DEFAULT_JSON_FORMATTER = new JsonCompactFormatter();
|
||||||
static final FieldNamingStrategy DEFAULT_NAMING_POLICY =
|
static final FieldNamingStrategy2 DEFAULT_NAMING_POLICY =
|
||||||
new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
|
new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
|
||||||
|
|
||||||
private static final ExclusionStrategy DEFAULT_EXCLUSION_STRATEGY =
|
private static final ExclusionStrategy DEFAULT_EXCLUSION_STRATEGY =
|
||||||
|
@ -98,7 +98,7 @@ public final class Gson {
|
||||||
|
|
||||||
private final ExclusionStrategy deserializationStrategy;
|
private final ExclusionStrategy deserializationStrategy;
|
||||||
|
|
||||||
private final FieldNamingStrategy fieldNamingPolicy;
|
private final FieldNamingStrategy2 fieldNamingPolicy;
|
||||||
private final MappedObjectConstructor objectConstructor;
|
private final MappedObjectConstructor objectConstructor;
|
||||||
|
|
||||||
/** Map containing Type or Class objects as keys */
|
/** Map containing Type or Class objects as keys */
|
||||||
|
@ -154,7 +154,7 @@ public final class Gson {
|
||||||
}
|
}
|
||||||
|
|
||||||
Gson(ExclusionStrategy serializationStrategy, ExclusionStrategy deserializationStrategy,
|
Gson(ExclusionStrategy serializationStrategy, ExclusionStrategy deserializationStrategy,
|
||||||
FieldNamingStrategy fieldNamingPolicy, MappedObjectConstructor objectConstructor,
|
FieldNamingStrategy2 fieldNamingPolicy, MappedObjectConstructor objectConstructor,
|
||||||
JsonFormatter formatter, boolean serializeNulls,
|
JsonFormatter formatter, boolean serializeNulls,
|
||||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
||||||
|
|
|
@ -69,7 +69,7 @@ public final class GsonBuilder {
|
||||||
private boolean serializeInnerClasses;
|
private boolean serializeInnerClasses;
|
||||||
private boolean excludeFieldsWithoutExposeAnnotation;
|
private boolean excludeFieldsWithoutExposeAnnotation;
|
||||||
private LongSerializationPolicy longSerializationPolicy;
|
private LongSerializationPolicy longSerializationPolicy;
|
||||||
private FieldNamingStrategy fieldNamingPolicy;
|
private FieldNamingStrategy2 fieldNamingPolicy;
|
||||||
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators;
|
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators;
|
||||||
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
|
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
|
||||||
private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
|
private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
|
||||||
|
@ -220,8 +220,22 @@ public final class GsonBuilder {
|
||||||
* @param fieldNamingStrategy the actual naming strategy to apply to the fields
|
* @param fieldNamingStrategy the actual naming strategy to apply to the fields
|
||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
* @since 1.3
|
* @since 1.3
|
||||||
|
* @deprecated use {@link #setFieldNamingStrategy(FieldNamingStrategy2)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
|
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
|
||||||
|
return setFieldNamingStrategy(new FieldNamingStrategy2Adapter(fieldNamingStrategy));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to apply a specific naming policy strategy to an object's field during
|
||||||
|
* serialization and deserialization.
|
||||||
|
*
|
||||||
|
* @param fieldNamingStrategy the actual naming strategy to apply to the fields
|
||||||
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy2 fieldNamingStrategy) {
|
||||||
this.fieldNamingPolicy =
|
this.fieldNamingPolicy =
|
||||||
new SerializedNameAnnotationInterceptingNamingPolicy(fieldNamingStrategy);
|
new SerializedNameAnnotationInterceptingNamingPolicy(fieldNamingStrategy);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.google.gson;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple implementation of the {@link FieldNamingStrategy} interface such that it does not
|
* A simple implementation of the {@link FieldNamingStrategy} interface such that it does not
|
||||||
|
@ -44,7 +45,7 @@ import java.lang.reflect.Type;
|
||||||
class JavaFieldNamingPolicy extends RecursiveFieldNamingPolicy {
|
class JavaFieldNamingPolicy extends RecursiveFieldNamingPolicy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String translateName(String target, Type fieldType, Annotation[] annotations) {
|
protected String translateName(String target, Type fieldType, Collection<Annotation> annotations) {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,17 +90,17 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
|
||||||
throw new JsonParseException("Expecting array but found object: " + node);
|
throw new JsonParseException("Expecting array but found object: " + node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitArrayField(Field f, Type typeOfF, Object obj) {
|
public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
|
||||||
throw new JsonParseException("Expecting array but found array field " + f.getName() + ": "
|
throw new JsonParseException("Expecting array but found array field " + f.getName() + ": "
|
||||||
+ obj);
|
+ obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitObjectField(Field f, Type typeOfF, Object obj) {
|
public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
|
||||||
throw new JsonParseException("Expecting array but found object field " + f.getName() + ": "
|
throw new JsonParseException("Expecting array but found object field " + f.getName() + ": "
|
||||||
+ obj);
|
+ obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean visitFieldUsingCustomHandler(Field f, Type actualTypeOfField, Object parent) {
|
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type actualTypeOfField, Object parent) {
|
||||||
throw new JsonParseException("Expecting array but found field " + f.getName() + ": "
|
throw new JsonParseException("Expecting array but found field " + f.getName() + ": "
|
||||||
+ parent);
|
+ parent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +49,7 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
|
||||||
throw new JsonParseException("Expecting object but found array: " + array);
|
throw new JsonParseException("Expecting object but found array: " + array);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitObjectField(Field f, Type typeOfF, Object obj) {
|
public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
|
||||||
try {
|
try {
|
||||||
if (!json.isJsonObject()) {
|
if (!json.isJsonObject()) {
|
||||||
throw new JsonParseException("Expecting object found: " + json);
|
throw new JsonParseException("Expecting object found: " + json);
|
||||||
|
@ -69,7 +68,7 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitArrayField(Field f, Type typeOfF, Object obj) {
|
public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
|
||||||
try {
|
try {
|
||||||
if (!json.isJsonObject()) {
|
if (!json.isJsonObject()) {
|
||||||
throw new JsonParseException("Expecting object found: " + json);
|
throw new JsonParseException("Expecting object found: " + json);
|
||||||
|
@ -88,12 +87,12 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFieldName(Field f) {
|
private String getFieldName(FieldAttributes f) {
|
||||||
FieldNamingStrategy namingPolicy = factory.getFieldNamingPolicy();
|
FieldNamingStrategy2 namingPolicy = factory.getFieldNamingPolicy();
|
||||||
return namingPolicy.translateName(f);
|
return namingPolicy.translateName(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean visitFieldUsingCustomHandler(Field f, Type declaredTypeOfField, Object parent) {
|
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type declaredTypeOfField, Object parent) {
|
||||||
try {
|
try {
|
||||||
String fName = getFieldName(f);
|
String fName = getFieldName(f);
|
||||||
if (!json.isJsonObject()) {
|
if (!json.isJsonObject()) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,7 +83,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitArrayField(Field f, Type typeOfF, Object obj) {
|
public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
|
||||||
try {
|
try {
|
||||||
if (isFieldNull(f, obj)) {
|
if (isFieldNull(f, obj)) {
|
||||||
if (serializeNulls) {
|
if (serializeNulls) {
|
||||||
|
@ -99,7 +98,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitObjectField(Field f, Type typeOfF, Object obj) {
|
public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
|
||||||
try {
|
try {
|
||||||
if (isFieldNull(f, obj)) {
|
if (isFieldNull(f, obj)) {
|
||||||
if (serializeNulls) {
|
if (serializeNulls) {
|
||||||
|
@ -122,13 +121,13 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
assignToRoot(json);
|
assignToRoot(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAsChildOfObject(Field f, ObjectTypePair fieldValuePair) {
|
private void addAsChildOfObject(FieldAttributes f, ObjectTypePair fieldValuePair) {
|
||||||
JsonElement childElement = getJsonElementForChild(fieldValuePair);
|
JsonElement childElement = getJsonElementForChild(fieldValuePair);
|
||||||
addChildAsElement(f, childElement);
|
addChildAsElement(f, childElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addChildAsElement(Field f, JsonElement childElement) {
|
private void addChildAsElement(FieldAttributes f, JsonElement childElement) {
|
||||||
FieldNamingStrategy namingPolicy = factory.getFieldNamingPolicy();
|
FieldNamingStrategy2 namingPolicy = factory.getFieldNamingPolicy();
|
||||||
root.getAsJsonObject().add(namingPolicy.translateName(f), childElement);
|
root.getAsJsonObject().add(namingPolicy.translateName(f), childElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +190,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean visitFieldUsingCustomHandler(Field f, Type declaredTypeOfField, Object parent) {
|
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type declaredTypeOfField, Object parent) {
|
||||||
try {
|
try {
|
||||||
Preconditions.checkState(root.isJsonObject());
|
Preconditions.checkState(root.isJsonObject());
|
||||||
Object obj = f.get(parent);
|
Object obj = f.get(parent);
|
||||||
|
@ -221,11 +220,11 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
root = newRoot;
|
root = newRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFieldNull(Field f, Object obj) {
|
private boolean isFieldNull(FieldAttributes f, Object obj) {
|
||||||
return getFieldValue(f, obj) == null;
|
return getFieldValue(f, obj) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object getFieldValue(Field f, Object obj) {
|
private Object getFieldValue(FieldAttributes f, Object obj) {
|
||||||
try {
|
try {
|
||||||
return f.get(obj);
|
return f.get(obj);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
|
|
|
@ -18,12 +18,13 @@ package com.google.gson;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FieldNamingStrategy} that ensures the JSON field names consist of only
|
* A {@link FieldNamingStrategy} that ensures the JSON field names consist of only
|
||||||
* lower case letters.
|
* lower case letters.
|
||||||
*
|
*
|
||||||
*<p>The following is an example:</p>
|
* <p>The following is an example:</p>
|
||||||
* <pre>
|
* <pre>
|
||||||
* class IntWrapper {
|
* class IntWrapper {
|
||||||
* public int integerField = 0;
|
* public int integerField = 0;
|
||||||
|
@ -36,12 +37,14 @@ import java.lang.reflect.Type;
|
||||||
* assert("integerfield".equals(translatedFieldName));
|
* assert("integerfield".equals(translatedFieldName));
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
* @author Inderjeet Singh
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
*/
|
*/
|
||||||
class LowerCaseNamingPolicy extends RecursiveFieldNamingPolicy {
|
class LowerCaseNamingPolicy extends RecursiveFieldNamingPolicy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String translateName(String target, Type fieldType, Annotation[] annotations) {
|
protected String translateName(String target, Type fieldType,
|
||||||
|
Collection<Annotation> annotations) {
|
||||||
return target.toLowerCase();
|
return target.toLowerCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.google.gson;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FieldNamingStrategy} that ensures the JSON field names begins with
|
* A {@link FieldNamingStrategy} that ensures the JSON field names begins with
|
||||||
|
@ -67,7 +68,8 @@ class ModifyFirstLetterNamingPolicy extends RecursiveFieldNamingPolicy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String translateName(String target, Type fieldType, Annotation[] annotations) {
|
protected String translateName(String target, Type fieldType,
|
||||||
|
Collection<Annotation> annotations) {
|
||||||
StringBuilder fieldNameBuilder = new StringBuilder();
|
StringBuilder fieldNameBuilder = new StringBuilder();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
char firstCharacter = target.charAt(index);
|
char firstCharacter = target.charAt(index);
|
||||||
|
|
|
@ -21,7 +21,8 @@ import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides ability to apply a visitor to an object and all of its fields recursively.
|
* Provides ability to apply a visitor to an object and all of its fields
|
||||||
|
* recursively.
|
||||||
*
|
*
|
||||||
* @author Inderjeet Singh
|
* @author Inderjeet Singh
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
|
@ -30,10 +31,12 @@ final class ObjectNavigator {
|
||||||
|
|
||||||
public interface Visitor {
|
public interface Visitor {
|
||||||
public void start(ObjectTypePair node);
|
public void start(ObjectTypePair node);
|
||||||
|
|
||||||
public void end(ObjectTypePair node);
|
public void end(ObjectTypePair node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called before the object navigator starts visiting the current object
|
* This is called before the object navigator starts visiting the current
|
||||||
|
* object
|
||||||
*/
|
*/
|
||||||
void startVisitingObject(Object node);
|
void startVisitingObject(Object node);
|
||||||
|
|
||||||
|
@ -45,23 +48,26 @@ final class ObjectNavigator {
|
||||||
/**
|
/**
|
||||||
* This is called to visit an object field of the current object
|
* This is called to visit an object field of the current object
|
||||||
*/
|
*/
|
||||||
void visitObjectField(Field f, Type typeOfF, Object obj);
|
void visitObjectField(FieldAttributes f, Type typeOfF, Object obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called to visit an array field of the current object
|
* This is called to visit an array field of the current object
|
||||||
*/
|
*/
|
||||||
void visitArrayField(Field f, Type typeOfF, Object obj);
|
void visitArrayField(FieldAttributes f, Type typeOfF, Object obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called to visit an object using a custom handler
|
* This is called to visit an object using a custom handler
|
||||||
|
*
|
||||||
* @return true if a custom handler exists, false otherwise
|
* @return true if a custom handler exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean visitUsingCustomHandler(ObjectTypePair objTypePair);
|
public boolean visitUsingCustomHandler(ObjectTypePair objTypePair);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called to visit a field of the current object using a custom handler
|
* This is called to visit a field of the current object using a custom
|
||||||
|
* handler
|
||||||
*/
|
*/
|
||||||
public boolean visitFieldUsingCustomHandler(Field f, Type actualTypeOfField, Object parent);
|
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type actualTypeOfField,
|
||||||
|
Object parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the current target
|
* Retrieve the current target
|
||||||
|
@ -75,9 +81,11 @@ final class ObjectNavigator {
|
||||||
private final ObjectTypePair objTypePair;
|
private final ObjectTypePair objTypePair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param objTypePair The object,type (fully genericized) being navigated
|
* @param objTypePair
|
||||||
* @param exclusionStrategy the concrete strategy object to be used to
|
* The object,type (fully genericized) being navigated
|
||||||
* filter out fields of an object.
|
* @param exclusionStrategy
|
||||||
|
* the concrete strategy object to be used to filter out fields of an
|
||||||
|
* object.
|
||||||
*/
|
*/
|
||||||
ObjectNavigator(ObjectTypePair objTypePair, ExclusionStrategy exclusionStrategy) {
|
ObjectNavigator(ObjectTypePair objTypePair, ExclusionStrategy exclusionStrategy) {
|
||||||
Preconditions.checkNotNull(exclusionStrategy);
|
Preconditions.checkNotNull(exclusionStrategy);
|
||||||
|
@ -87,8 +95,8 @@ final class ObjectNavigator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigate all the fields of the specified object.
|
* Navigate all the fields of the specified object. If a field is null, it
|
||||||
* If a field is null, it does not get visited.
|
* does not get visited.
|
||||||
*/
|
*/
|
||||||
public void accept(Visitor visitor) {
|
public void accept(Visitor visitor) {
|
||||||
TypeInfo objTypeInfo = new TypeInfo(objTypePair.type);
|
TypeInfo objTypeInfo = new TypeInfo(objTypePair.type);
|
||||||
|
@ -110,15 +118,15 @@ final class ObjectNavigator {
|
||||||
} else if (objTypeInfo.getActualType() == Object.class
|
} else if (objTypeInfo.getActualType() == Object.class
|
||||||
&& isPrimitiveOrString(objectToVisit)) {
|
&& isPrimitiveOrString(objectToVisit)) {
|
||||||
// TODO(Joel): this is only used for deserialization of "primitives"
|
// TODO(Joel): this is only used for deserialization of "primitives"
|
||||||
// we should rethink this!!!
|
// we should rethink this!!!
|
||||||
visitor.visitPrimitive(objectToVisit);
|
visitor.visitPrimitive(objectToVisit);
|
||||||
objectToVisit = visitor.getTarget();
|
objectToVisit = visitor.getTarget();
|
||||||
} else {
|
} else {
|
||||||
visitor.startVisitingObject(objectToVisit);
|
visitor.startVisitingObject(objectToVisit);
|
||||||
ObjectTypePair currObjTypePair = objTypePair.toMoreSpecificType();
|
ObjectTypePair currObjTypePair = objTypePair.toMoreSpecificType();
|
||||||
Class<?> topLevelClass = new TypeInfo(currObjTypePair.type).getRawClass();
|
Class<?> topLevelClass = new TypeInfo(currObjTypePair.type).getRawClass();
|
||||||
for (Class<?> curr = topLevelClass; curr != null && !curr.equals(Object.class);
|
for (Class<?> curr = topLevelClass; curr != null && !curr.equals(Object.class); curr =
|
||||||
curr = curr.getSuperclass()) {
|
curr.getSuperclass()) {
|
||||||
if (!curr.isSynthetic()) {
|
if (!curr.isSynthetic()) {
|
||||||
navigateClassFields(objectToVisit, curr, visitor);
|
navigateClassFields(objectToVisit, curr, visitor);
|
||||||
}
|
}
|
||||||
|
@ -148,12 +156,12 @@ final class ObjectNavigator {
|
||||||
TypeInfo fieldTypeInfo = TypeInfoFactory.getTypeInfoForField(f, objTypePair.type);
|
TypeInfo fieldTypeInfo = TypeInfoFactory.getTypeInfoForField(f, objTypePair.type);
|
||||||
Type declaredTypeOfField = fieldTypeInfo.getActualType();
|
Type declaredTypeOfField = fieldTypeInfo.getActualType();
|
||||||
boolean visitedWithCustomHandler =
|
boolean visitedWithCustomHandler =
|
||||||
visitor.visitFieldUsingCustomHandler(f, declaredTypeOfField, obj);
|
visitor.visitFieldUsingCustomHandler(fieldAttributes, declaredTypeOfField, obj);
|
||||||
if (!visitedWithCustomHandler) {
|
if (!visitedWithCustomHandler) {
|
||||||
if (fieldTypeInfo.isArray()) {
|
if (fieldTypeInfo.isArray()) {
|
||||||
visitor.visitArrayField(f, declaredTypeOfField, obj);
|
visitor.visitArrayField(fieldAttributes, declaredTypeOfField, obj);
|
||||||
} else {
|
} else {
|
||||||
visitor.visitObjectField(f, declaredTypeOfField, obj);
|
visitor.visitObjectField(fieldAttributes, declaredTypeOfField, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ package com.google.gson;
|
||||||
*/
|
*/
|
||||||
final class ObjectNavigatorFactory {
|
final class ObjectNavigatorFactory {
|
||||||
private final ExclusionStrategy strategy;
|
private final ExclusionStrategy strategy;
|
||||||
private final FieldNamingStrategy fieldNamingPolicy;
|
private final FieldNamingStrategy2 fieldNamingPolicy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a factory object that will be able to create new
|
* Creates a factory object that will be able to create new
|
||||||
|
@ -36,7 +36,7 @@ final class ObjectNavigatorFactory {
|
||||||
* @param fieldNamingPolicy the naming policy that should be applied to field
|
* @param fieldNamingPolicy the naming policy that should be applied to field
|
||||||
* names
|
* names
|
||||||
*/
|
*/
|
||||||
public ObjectNavigatorFactory(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy) {
|
public ObjectNavigatorFactory(ExclusionStrategy strategy, FieldNamingStrategy2 fieldNamingPolicy) {
|
||||||
Preconditions.checkNotNull(fieldNamingPolicy);
|
Preconditions.checkNotNull(fieldNamingPolicy);
|
||||||
this.strategy = (strategy == null ? new NullExclusionStrategy() : strategy);
|
this.strategy = (strategy == null ? new NullExclusionStrategy() : strategy);
|
||||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
this.fieldNamingPolicy = fieldNamingPolicy;
|
||||||
|
@ -55,7 +55,7 @@ final class ObjectNavigatorFactory {
|
||||||
return new ObjectNavigator(objTypePair, strategy);
|
return new ObjectNavigator(objTypePair, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldNamingStrategy getFieldNamingPolicy() {
|
FieldNamingStrategy2 getFieldNamingPolicy() {
|
||||||
return fieldNamingPolicy;
|
return fieldNamingPolicy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,18 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple object that holds onto a pair of object references, first and second.
|
||||||
|
*
|
||||||
|
* @author Inderjeet Singh
|
||||||
|
* @author Joel Leitch
|
||||||
|
*
|
||||||
|
* @param <FIRST>
|
||||||
|
* @param <SECOND>
|
||||||
|
*/
|
||||||
final class Pair<FIRST, SECOND> {
|
final class Pair<FIRST, SECOND> {
|
||||||
|
|
||||||
final FIRST first;
|
final FIRST first;
|
||||||
|
@ -24,4 +34,24 @@ final class Pair<FIRST, SECOND> {
|
||||||
this.first = first;
|
this.first = first;
|
||||||
this.second = second;
|
this.second = second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 17 * ((first != null) ? first.hashCode() : 0)
|
||||||
|
+ 17 * ((second != null) ? second.hashCode() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof Pair<?, ?>)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<?, ?> that = (Pair<?, ?>) o;
|
||||||
|
return equal(this.first, that.first) && equal(this.second, that.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean equal(Object a, Object b) {
|
||||||
|
return a == b || (a != null && a.equals(b));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -17,8 +17,8 @@
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mechanism for providing custom field naming in Gson. This allows the client code to translate
|
* A mechanism for providing custom field naming in Gson. This allows the client code to translate
|
||||||
|
@ -27,11 +27,11 @@ import java.lang.reflect.Type;
|
||||||
*
|
*
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
*/
|
*/
|
||||||
abstract class RecursiveFieldNamingPolicy implements FieldNamingStrategy {
|
abstract class RecursiveFieldNamingPolicy implements FieldNamingStrategy2 {
|
||||||
|
|
||||||
public final String translateName(Field f) {
|
public final String translateName(FieldAttributes f) {
|
||||||
Preconditions.checkNotNull(f);
|
Preconditions.checkNotNull(f);
|
||||||
return translateName(f.getName(), f.getGenericType(), f.getAnnotations());
|
return translateName(f.getName(), f.getDeclaredType(), f.getAnnotations());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,5 +42,5 @@ abstract class RecursiveFieldNamingPolicy implements FieldNamingStrategy {
|
||||||
* @param annotations the annotations set on the field
|
* @param annotations the annotations set on the field
|
||||||
* @return the translated field name
|
* @return the translated field name
|
||||||
*/
|
*/
|
||||||
protected abstract String translateName(String target, Type fieldType, Annotation[] annotations);
|
protected abstract String translateName(String target, Type fieldType, Collection<Annotation> annotations);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@ package com.google.gson;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FieldNamingStrategy} that acts as a chain of responsibility. If the
|
* A {@link FieldNamingStrategy} that acts as a chain of responsibility. If the
|
||||||
* {@link com.google.gson.annotations.SerializedName} annotation is applied to a field then this
|
* {@link com.google.gson.annotations.SerializedName} annotation is applied to a field then this
|
||||||
|
@ -33,15 +31,15 @@ import java.lang.reflect.Field;
|
||||||
*
|
*
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
*/
|
*/
|
||||||
final class SerializedNameAnnotationInterceptingNamingPolicy implements FieldNamingStrategy {
|
final class SerializedNameAnnotationInterceptingNamingPolicy implements FieldNamingStrategy2 {
|
||||||
private static final JsonFieldNameValidator fieldNameValidator = new JsonFieldNameValidator();
|
private static final JsonFieldNameValidator fieldNameValidator = new JsonFieldNameValidator();
|
||||||
private final FieldNamingStrategy delegate;
|
private final FieldNamingStrategy2 delegate;
|
||||||
|
|
||||||
public SerializedNameAnnotationInterceptingNamingPolicy(FieldNamingStrategy delegate) {
|
public SerializedNameAnnotationInterceptingNamingPolicy(FieldNamingStrategy2 delegate) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String translateName(Field f) {
|
public String translateName(FieldAttributes f) {
|
||||||
Preconditions.checkNotNull(f);
|
Preconditions.checkNotNull(f);
|
||||||
SerializedName serializedName = f.getAnnotation(SerializedName.class);
|
SerializedName serializedName = f.getAnnotation(SerializedName.class);
|
||||||
if (serializedName != null) {
|
if (serializedName != null) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.google.gson;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FieldNamingStrategy} that ensures the JSON field names consist of only
|
* A {@link FieldNamingStrategy} that ensures the JSON field names consist of only
|
||||||
|
@ -41,7 +42,7 @@ import java.lang.reflect.Type;
|
||||||
class UpperCaseNamingPolicy extends RecursiveFieldNamingPolicy {
|
class UpperCaseNamingPolicy extends RecursiveFieldNamingPolicy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String translateName(String target, Type fieldType, Annotation[] annotations) {
|
protected String translateName(String target, Type fieldType, Collection<Annotation> annotations) {
|
||||||
return target.toUpperCase();
|
return target.toUpperCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@ package com.google.gson;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the {@link JavaFieldNamingPolicy} class.
|
* Tests for the {@link JavaFieldNamingPolicy} class.
|
||||||
*
|
*
|
||||||
|
@ -36,13 +34,13 @@ public class JavaFieldNamingPolicyTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFieldNamingPolicy() throws Exception {
|
public void testFieldNamingPolicy() throws Exception {
|
||||||
Field f = String.class.getFields()[0];
|
FieldAttributes f = new FieldAttributes(String.class.getFields()[0]);
|
||||||
assertEquals(f.getName(), namingPolicy.translateName(f));
|
assertEquals(f.getName(), namingPolicy.translateName(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNullField() throws Exception {
|
public void testNullField() throws Exception {
|
||||||
try {
|
try {
|
||||||
namingPolicy.translateName((Field) null);
|
namingPolicy.translateName((FieldAttributes) null);
|
||||||
fail("Should have thrown an exception");
|
fail("Should have thrown an exception");
|
||||||
} catch (IllegalArgumentException expected) { }
|
} catch (IllegalArgumentException expected) { }
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,9 @@
|
||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the {@link SerializedNameAnnotationInterceptingNamingPolicy} class.
|
* Unit tests for the {@link SerializedNameAnnotationInterceptingNamingPolicy} class.
|
||||||
|
@ -40,7 +38,7 @@ public class SerializedNameAnnotationInterceptingNamingPolicyTest extends TestCa
|
||||||
|
|
||||||
public void testFieldWithAnnotation() throws Exception {
|
public void testFieldWithAnnotation() throws Exception {
|
||||||
String fieldName = "fieldWithAnnotation";
|
String fieldName = "fieldWithAnnotation";
|
||||||
Field f = SomeObject.class.getField(fieldName);
|
FieldAttributes f = new FieldAttributes(SomeObject.class.getField(fieldName));
|
||||||
|
|
||||||
assertFalse(ANNOTATED_FIELD_NAME.equals(fieldName));
|
assertFalse(ANNOTATED_FIELD_NAME.equals(fieldName));
|
||||||
assertEquals(ANNOTATED_FIELD_NAME, policy.translateName(f));
|
assertEquals(ANNOTATED_FIELD_NAME, policy.translateName(f));
|
||||||
|
@ -48,7 +46,7 @@ public class SerializedNameAnnotationInterceptingNamingPolicyTest extends TestCa
|
||||||
|
|
||||||
public void testFieldWithoutAnnotation() throws Exception {
|
public void testFieldWithoutAnnotation() throws Exception {
|
||||||
String fieldName = "fieldWithoutAnnotation";
|
String fieldName = "fieldWithoutAnnotation";
|
||||||
Field f = SomeObject.class.getField(fieldName);
|
FieldAttributes f = new FieldAttributes(SomeObject.class.getField(fieldName));
|
||||||
|
|
||||||
assertEquals(fieldName, policy.translateName(f));
|
assertEquals(fieldName, policy.translateName(f));
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,7 +426,6 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DataHolder {
|
private static class DataHolder {
|
||||||
@SuppressWarnings("unused")
|
|
||||||
final String data;
|
final String data;
|
||||||
|
|
||||||
// For use by Gson
|
// For use by Gson
|
||||||
|
|
Loading…
Reference in New Issue
Block a user