Performance fixes after doing some profiling.
This commit is contained in:
parent
6a80791f13
commit
764e4d9aca
@ -18,7 +18,6 @@ package com.google.gson;
|
|||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper class used to collect numerous {@link ExclusionStrategy} objects
|
* A wrapper class used to collect numerous {@link ExclusionStrategy} objects
|
||||||
@ -29,22 +28,9 @@ import java.util.LinkedList;
|
|||||||
final class DisjunctionExclusionStrategy implements ExclusionStrategy {
|
final class DisjunctionExclusionStrategy implements ExclusionStrategy {
|
||||||
private final Collection<ExclusionStrategy> strategies;
|
private final Collection<ExclusionStrategy> strategies;
|
||||||
|
|
||||||
public DisjunctionExclusionStrategy(ExclusionStrategy... strategies) {
|
|
||||||
Preconditions.checkNotNull(strategies);
|
|
||||||
Preconditions.checkArgument(strategies.length > 0);
|
|
||||||
|
|
||||||
this.strategies = new LinkedList<ExclusionStrategy>();
|
|
||||||
for (ExclusionStrategy strategy : strategies) {
|
|
||||||
this.strategies.add(strategy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
|
public DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
|
||||||
Preconditions.checkNotNull(strategies);
|
Preconditions.checkNotNull(strategies);
|
||||||
Preconditions.checkArgument(!strategies.isEmpty());
|
this.strategies = strategies;
|
||||||
|
|
||||||
this.strategies = new LinkedList<ExclusionStrategy>();
|
|
||||||
this.strategies.addAll(strategies);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldSkipField(Field f) {
|
public boolean shouldSkipField(Field f) {
|
||||||
|
@ -140,7 +140,7 @@ public final class Gson {
|
|||||||
*/
|
*/
|
||||||
Gson(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy) {
|
Gson(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy) {
|
||||||
this(strategy, fieldNamingPolicy,
|
this(strategy, fieldNamingPolicy,
|
||||||
createObjectConstructor(DefaultTypeAdapters.getDefaultInstanceCreators()),
|
new MappedObjectConstructor(DefaultTypeAdapters.getDefaultInstanceCreators()),
|
||||||
DEFAULT_JSON_FORMATTER, false, DefaultTypeAdapters.getDefaultSerializers(),
|
DEFAULT_JSON_FORMATTER, false, DefaultTypeAdapters.getDefaultSerializers(),
|
||||||
DefaultTypeAdapters.getDefaultDeserializers());
|
DefaultTypeAdapters.getDefaultDeserializers());
|
||||||
}
|
}
|
||||||
@ -158,15 +158,6 @@ public final class Gson {
|
|||||||
this.deserializers = deserializers;
|
this.deserializers = deserializers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MappedObjectConstructor createObjectConstructor(
|
|
||||||
ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators) {
|
|
||||||
MappedObjectConstructor objectConstructor = new MappedObjectConstructor();
|
|
||||||
for (Map.Entry<Type, InstanceCreator<?>> entry : instanceCreators.entrySet()) {
|
|
||||||
objectConstructor.register(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
return objectConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ObjectNavigatorFactory createDefaultObjectNavigatorFactory() {
|
private ObjectNavigatorFactory createDefaultObjectNavigatorFactory() {
|
||||||
return new ObjectNavigatorFactory(strategy, fieldNamingPolicy);
|
return new ObjectNavigatorFactory(strategy, fieldNamingPolicy);
|
||||||
}
|
}
|
||||||
|
@ -50,12 +50,16 @@ import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
|
|||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
*/
|
*/
|
||||||
public final class GsonBuilder {
|
public final class GsonBuilder {
|
||||||
|
private static final AnonymousAndLocalClassExclusionStrategy anonAndLocalClassExclusionStrategy =
|
||||||
|
new AnonymousAndLocalClassExclusionStrategy();
|
||||||
|
private static final InnerClassExclusionStrategy innerClassExclusionStrategy =
|
||||||
|
new InnerClassExclusionStrategy();
|
||||||
|
private static final ExposeAnnotationBasedExclusionStrategy exposeAnnotationExclusionStrategy =
|
||||||
|
new ExposeAnnotationBasedExclusionStrategy();
|
||||||
|
|
||||||
private double ignoreVersionsAfter;
|
private double ignoreVersionsAfter;
|
||||||
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
|
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
|
||||||
private boolean serializeInnerClasses;
|
private boolean serializeInnerClasses;
|
||||||
private final AnonymousAndLocalClassExclusionStrategy anonAndLocalClassExclusionStrategy;
|
|
||||||
private final InnerClassExclusionStrategy innerClassExclusionStrategy;
|
|
||||||
private boolean excludeFieldsWithoutExposeAnnotation;
|
private boolean excludeFieldsWithoutExposeAnnotation;
|
||||||
private LongSerializationPolicy longSerializationPolicy;
|
private LongSerializationPolicy longSerializationPolicy;
|
||||||
private FieldNamingStrategy fieldNamingPolicy;
|
private FieldNamingStrategy fieldNamingPolicy;
|
||||||
@ -82,8 +86,6 @@ public final class GsonBuilder {
|
|||||||
serializeInnerClasses = true;
|
serializeInnerClasses = true;
|
||||||
prettyPrinting = false;
|
prettyPrinting = false;
|
||||||
escapeHtmlChars = true;
|
escapeHtmlChars = true;
|
||||||
anonAndLocalClassExclusionStrategy = new AnonymousAndLocalClassExclusionStrategy();
|
|
||||||
innerClassExclusionStrategy = new InnerClassExclusionStrategy();
|
|
||||||
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
|
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
|
||||||
excludeFieldsWithoutExposeAnnotation = false;
|
excludeFieldsWithoutExposeAnnotation = false;
|
||||||
longSerializationPolicy = LongSerializationPolicy.DEFAULT;
|
longSerializationPolicy = LongSerializationPolicy.DEFAULT;
|
||||||
@ -399,7 +401,7 @@ public final class GsonBuilder {
|
|||||||
strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
||||||
}
|
}
|
||||||
if (excludeFieldsWithoutExposeAnnotation) {
|
if (excludeFieldsWithoutExposeAnnotation) {
|
||||||
strategies.add(new ExposeAnnotationBasedExclusionStrategy());
|
strategies.add(exposeAnnotationExclusionStrategy);
|
||||||
}
|
}
|
||||||
ExclusionStrategy exclusionStrategy = new DisjunctionExclusionStrategy(strategies);
|
ExclusionStrategy exclusionStrategy = new DisjunctionExclusionStrategy(strategies);
|
||||||
|
|
||||||
@ -414,9 +416,14 @@ public final class GsonBuilder {
|
|||||||
customDeserializers.registerIfAbsent(DefaultTypeAdapters.getDefaultDeserializers());
|
customDeserializers.registerIfAbsent(DefaultTypeAdapters.getDefaultDeserializers());
|
||||||
|
|
||||||
ParameterizedTypeHandlerMap<InstanceCreator<?>> customInstanceCreators =
|
ParameterizedTypeHandlerMap<InstanceCreator<?>> customInstanceCreators =
|
||||||
instanceCreators.copyOf();
|
instanceCreators.copyOf();
|
||||||
customInstanceCreators.registerIfAbsent(DefaultTypeAdapters.getDefaultInstanceCreators());
|
customInstanceCreators.registerIfAbsent(DefaultTypeAdapters.getDefaultInstanceCreators());
|
||||||
MappedObjectConstructor objConstructor = Gson.createObjectConstructor(customInstanceCreators);
|
|
||||||
|
customSerializers.makeUnmodifiable();
|
||||||
|
customDeserializers.makeUnmodifiable();
|
||||||
|
instanceCreators.makeUnmodifiable();
|
||||||
|
|
||||||
|
MappedObjectConstructor objConstructor = new MappedObjectConstructor(customInstanceCreators);
|
||||||
|
|
||||||
JsonFormatter formatter = prettyPrinting ?
|
JsonFormatter formatter = prettyPrinting ?
|
||||||
new JsonPrintFormatter(escapeHtmlChars) : new JsonCompactFormatter(escapeHtmlChars);
|
new JsonPrintFormatter(escapeHtmlChars) : new JsonCompactFormatter(escapeHtmlChars);
|
||||||
@ -428,18 +435,20 @@ public final class GsonBuilder {
|
|||||||
private static void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
|
private static void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
|
||||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
|
||||||
// NOTE: if a date pattern exists, then that style takes priority
|
if (!serializers.hasSpecificHandlerFor(Date.class)
|
||||||
DefaultDateTypeAdapter dateTypeAdapter = null;
|
|
||||||
if (datePattern != null && !"".equals(datePattern.trim())) {
|
|
||||||
dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
|
|
||||||
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
|
|
||||||
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
|
|
||||||
}
|
|
||||||
if (dateTypeAdapter != null
|
|
||||||
&& !serializers.hasSpecificHandlerFor(Date.class)
|
|
||||||
&& !deserializers.hasSpecificHandlerFor(Date.class)) {
|
&& !deserializers.hasSpecificHandlerFor(Date.class)) {
|
||||||
serializers.register(Date.class, dateTypeAdapter);
|
// NOTE: if a date pattern exists, then that style takes priority
|
||||||
deserializers.register(Date.class, dateTypeAdapter);
|
DefaultDateTypeAdapter dateTypeAdapter = null;
|
||||||
|
if (datePattern != null && !"".equals(datePattern.trim())) {
|
||||||
|
dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
|
||||||
|
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
|
||||||
|
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dateTypeAdapter != null) {
|
||||||
|
serializers.register(Date.class, dateTypeAdapter);
|
||||||
|
deserializers.register(Date.class, dateTypeAdapter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ final class JsonTreeNavigator {
|
|||||||
if (child.isJsonNull()) {
|
if (child.isJsonNull()) {
|
||||||
visitor.visitNullArrayMember(parent, isFirst);
|
visitor.visitNullArrayMember(parent, isFirst);
|
||||||
navigate(child);
|
navigate(child);
|
||||||
} else if (child.isJsonArray()) {
|
} else if (child.isJsonArray()) {
|
||||||
JsonArray childAsArray = child.getAsJsonArray();
|
JsonArray childAsArray = child.getAsJsonArray();
|
||||||
visitor.visitArrayMember(parent, childAsArray, isFirst);
|
visitor.visitArrayMember(parent, childAsArray, isFirst);
|
||||||
navigate(childAsArray);
|
navigate(childAsArray);
|
||||||
|
@ -37,8 +37,12 @@ import java.util.logging.Logger;
|
|||||||
final class MappedObjectConstructor implements ObjectConstructor {
|
final class MappedObjectConstructor implements ObjectConstructor {
|
||||||
private static final Logger log = Logger.getLogger(MappedObjectConstructor.class.getName());
|
private static final Logger log = Logger.getLogger(MappedObjectConstructor.class.getName());
|
||||||
|
|
||||||
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreatorMap =
|
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreatorMap;
|
||||||
new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
|
|
||||||
|
public MappedObjectConstructor(
|
||||||
|
ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators) {
|
||||||
|
instanceCreatorMap = instanceCreators;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T construct(Type typeOfT) {
|
public <T> T construct(Type typeOfT) {
|
||||||
|
@ -46,18 +46,6 @@ final class ObjectNavigatorFactory {
|
|||||||
this.stack = new MemoryRefStack<Object>();
|
this.stack = new MemoryRefStack<Object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link ObjectNavigator} for this {@code srcObject}.
|
|
||||||
*
|
|
||||||
* @see #create(Object, Type)
|
|
||||||
* @param srcObject object to navigate
|
|
||||||
* @return a new instance of a {@link ObjectNavigator} ready to navigate the
|
|
||||||
* {@code srcObject}.
|
|
||||||
*/
|
|
||||||
public ObjectNavigator create(Object srcObject) {
|
|
||||||
return create(srcObject, srcObject.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link ObjectNavigator} for this {@code srcObject},
|
* Creates a new {@link ObjectNavigator} for this {@code srcObject},
|
||||||
* {@code type} pair.
|
* {@code type} pair.
|
||||||
|
@ -38,41 +38,26 @@ public class DisjunctionExclusionStrategyTest extends TestCase {
|
|||||||
private static final Field FIELD = CLAZZ.getFields()[0];
|
private static final Field FIELD = CLAZZ.getFields()[0];
|
||||||
|
|
||||||
public void testBadInstantiation() throws Exception {
|
public void testBadInstantiation() throws Exception {
|
||||||
try {
|
|
||||||
new DisjunctionExclusionStrategy();
|
|
||||||
} catch (IllegalArgumentException expected) { }
|
|
||||||
|
|
||||||
try {
|
|
||||||
ExclusionStrategy[] constructorParam = null;
|
|
||||||
new DisjunctionExclusionStrategy(constructorParam);
|
|
||||||
} catch (IllegalArgumentException expected) { }
|
|
||||||
|
|
||||||
try {
|
|
||||||
ExclusionStrategy[] constructorParam = new ExclusionStrategy[0];
|
|
||||||
new DisjunctionExclusionStrategy(constructorParam);
|
|
||||||
} catch (IllegalArgumentException expected) { }
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<ExclusionStrategy> constructorParam = null;
|
List<ExclusionStrategy> constructorParam = null;
|
||||||
new DisjunctionExclusionStrategy(constructorParam);
|
new DisjunctionExclusionStrategy(constructorParam);
|
||||||
} catch (IllegalArgumentException expected) { }
|
} catch (IllegalArgumentException expected) { }
|
||||||
|
|
||||||
try {
|
|
||||||
List<ExclusionStrategy> constructorParam = new LinkedList<ExclusionStrategy>();
|
|
||||||
new DisjunctionExclusionStrategy(constructorParam);
|
|
||||||
} catch (IllegalArgumentException expected) { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSkipFieldsWithMixedTrueAndFalse() throws Exception {
|
public void testSkipFieldsWithMixedTrueAndFalse() throws Exception {
|
||||||
DisjunctionExclusionStrategy strategy =
|
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||||
new DisjunctionExclusionStrategy(FALSE_STRATEGY, TRUE_STRATEGY);
|
strategies.add(FALSE_STRATEGY);
|
||||||
|
strategies.add(TRUE_STRATEGY);
|
||||||
|
DisjunctionExclusionStrategy strategy = new DisjunctionExclusionStrategy(strategies);
|
||||||
|
|
||||||
assertTrue(strategy.shouldSkipClass(CLAZZ));
|
assertTrue(strategy.shouldSkipClass(CLAZZ));
|
||||||
assertTrue(strategy.shouldSkipField(FIELD));
|
assertTrue(strategy.shouldSkipField(FIELD));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSkipFieldsWithFalseOnly() throws Exception {
|
public void testSkipFieldsWithFalseOnly() throws Exception {
|
||||||
DisjunctionExclusionStrategy strategy = new DisjunctionExclusionStrategy(FALSE_STRATEGY);
|
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||||
|
strategies.add(FALSE_STRATEGY);
|
||||||
|
DisjunctionExclusionStrategy strategy = new DisjunctionExclusionStrategy(strategies);
|
||||||
|
|
||||||
assertFalse(strategy.shouldSkipClass(CLAZZ));
|
assertFalse(strategy.shouldSkipClass(CLAZZ));
|
||||||
assertFalse(strategy.shouldSkipField(FIELD));
|
assertFalse(strategy.shouldSkipField(FIELD));
|
||||||
|
Loading…
Reference in New Issue
Block a user