Provide a means to add serialization or deserialization specific exclusion strategies.
This commit is contained in:
parent
ea48a1debf
commit
114633fbf9
@ -21,13 +21,13 @@ package com.google.gson;
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class AnonymousAndLocalClassExclusionStrategy implements ExclusionStrategy2 {
|
||||
final class AnonymousAndLocalClassExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return isAnonymousOrLocal(f.getDeclaredClass());
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return isAnonymousOrLocal(clazz);
|
||||
}
|
||||
|
||||
|
@ -19,31 +19,31 @@ package com.google.gson;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A wrapper class used to collect numerous {@link ExclusionStrategy2} objects
|
||||
* A wrapper class used to collect numerous {@link ExclusionStrategy} objects
|
||||
* and perform a short-circuited OR operation.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class DisjunctionExclusionStrategy implements ExclusionStrategy2 {
|
||||
private final Collection<ExclusionStrategy2> strategies;
|
||||
final class DisjunctionExclusionStrategy implements ExclusionStrategy {
|
||||
private final Collection<ExclusionStrategy> strategies;
|
||||
|
||||
public DisjunctionExclusionStrategy(Collection<ExclusionStrategy2> strategies) {
|
||||
public DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
|
||||
Preconditions.checkNotNull(strategies);
|
||||
this.strategies = strategies;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
for (ExclusionStrategy2 strategy : strategies) {
|
||||
if (strategy.shouldSkipField(f, mode)) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
for (ExclusionStrategy strategy : strategies) {
|
||||
if (strategy.shouldSkipField(f)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
for (ExclusionStrategy2 strategy : strategies) {
|
||||
if (strategy.shouldSkipClass(clazz, mode)) {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
for (ExclusionStrategy strategy : strategies) {
|
||||
if (strategy.shouldSkipClass(clazz)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,10 @@ package com.google.gson;
|
||||
* .setExclusionStrategies(excludeStrings)
|
||||
* .create();
|
||||
* </pre>
|
||||
*
|
||||
* <p>For certain model classes, you may only want to serialize a field, but exclude it for
|
||||
* deserialization. To do that, you can write an {@code ExclusionStrategy} as per normal;
|
||||
* however, you would register it with the
|
||||
*
|
||||
* @author Inderjeet Singh
|
||||
* @author Joel Leitch
|
||||
@ -78,9 +82,7 @@ package com.google.gson;
|
||||
* @see GsonBuilder#setExclusionStrategies(ExclusionStrategy...)
|
||||
*
|
||||
* @since 1.4
|
||||
* @deprecated use the more powerful {@link ExclusionStrategy2} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ExclusionStrategy {
|
||||
|
||||
/**
|
||||
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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;
|
||||
|
||||
/**
|
||||
* A strategy (or policy) definition that is used to decide whether or not a field or top-level
|
||||
* class should be serialized or deserialized as part of the JSON output/input. For serialization,
|
||||
* if the {@link #shouldSkipClass(Class, Mode)} method returns false then that class or field
|
||||
* type will not be part of the JSON output. For deserialization, if
|
||||
* {@link #shouldSkipClass(Class, , Context)} returns false, then it will not be set as part of
|
||||
* the Java object structure.
|
||||
*
|
||||
* <p>The following are a few examples that shows how you can use this exclusion mechanism.
|
||||
*
|
||||
* <p><strong>Exclude fields and objects based on a particular class type for both serialization
|
||||
* and deserialization:</strong>
|
||||
* <pre class="code">
|
||||
* public class SpecificClassExclusionStrategy implements ExclusionStrategy2 {
|
||||
* private final Class<?> excludedThisClass;
|
||||
*
|
||||
* public SpecificClassExclusionStrategy(Class<?> excludedThisClass) {
|
||||
* this.excludedThisClass = excludedThisClass;
|
||||
* }
|
||||
*
|
||||
* public boolean shouldSkipClass(Class<?> clazz, Context context) {
|
||||
* return excludedThisClass.equals(clazz);
|
||||
* }
|
||||
*
|
||||
* public boolean shouldSkipField(FieldAttributes f, Context context) {
|
||||
* return excludedThisClass.equals(f.getDeclaredClass());
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p><strong>Excludes fields and objects based on a particular annotation for both serialization
|
||||
* and deserialization:</strong>
|
||||
* <pre class="code">
|
||||
* public @interface FooAnnotation {
|
||||
* // some implementation here
|
||||
* }
|
||||
*
|
||||
* // Excludes any field (or class) that is tagged with an "@FooAnnotation"
|
||||
* public class FooAnnotationExclusionStrategy implements ExclusionStrategy2 {
|
||||
* public boolean shouldSkipClass(Class<?> clazz, Context context) {
|
||||
* return clazz.getAnnotation(FooAnnotation.class) != null;
|
||||
* }
|
||||
*
|
||||
* public boolean shouldSkipField(FieldAttributes f, Context context) {
|
||||
* return f.getAnnotation(FooAnnotation.class) != null;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p><strong>Exclude fields and objects based on a particular class type for serialization
|
||||
* only:</strong>
|
||||
* <pre class="code">
|
||||
* public class SpecificClassExclusionStrategy implements ExclusionStrategy2 {
|
||||
* private final Class<?> excludedThisClass;
|
||||
*
|
||||
* public SpecificClassExclusionStrategy(Class<?> excludedThisClass) {
|
||||
* this.excludedThisClass = excludedThisClass;
|
||||
* }
|
||||
*
|
||||
* public boolean shouldSkipClass(Class<?> clazz, Context context) {
|
||||
* if (context == Context.SERIALIZE) {
|
||||
* return excludedThisClass.equals(clazz);
|
||||
* } else {
|
||||
* return false;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* public boolean shouldSkipField(FieldAttributes f, Context context) {
|
||||
* if (context == Context.SERIALIZE) {
|
||||
* return excludedThisClass.equals(f.getDeclaredClass());
|
||||
* } else {
|
||||
* return false;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>Now if you want to configure {@code Gson} to use a user defined exclusion strategy, then
|
||||
* the {@code GsonBuilder} is required. The following is an example of how you can use the
|
||||
* {@code GsonBuilder} to configure Gson to use one of the above sample:
|
||||
* <pre class="code">
|
||||
* ExclusionStrategy2 excludeStrings = new UserDefinedExclusionStrategy(String.class);
|
||||
* Gson gson = new GsonBuilder()
|
||||
* .setExclusionStrategies(excludeStrings)
|
||||
* .create();
|
||||
* </pre>
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface ExclusionStrategy2 {
|
||||
|
||||
/**
|
||||
* @param f the field object that is under test
|
||||
* @param mode the current mode the Gson is running in
|
||||
* @return true if the field should be ignored; otherwise false
|
||||
*/
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode);
|
||||
|
||||
/**
|
||||
* @param clazz the class object that is under test
|
||||
* @param mode the current mode the Gson is running in
|
||||
* @return true if the class should be ignored; otherwise false
|
||||
*/
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode);
|
||||
}
|
@ -23,23 +23,16 @@ import com.google.gson.annotations.Expose;
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public class ExposeAnnotationExclusionStrategy implements ExclusionStrategy2 {
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
public class ExposeAnnotationDeserializationExclusionStrategy implements ExclusionStrategy {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
Expose annotation = f.getAnnotation(Expose.class);
|
||||
if (annotation == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mode == Mode.SERIALIZE) {
|
||||
return !annotation.serialize();
|
||||
} else if (mode == Mode.DESERIALIZE) {
|
||||
return !annotation.deserialize();
|
||||
}
|
||||
|
||||
return false;
|
||||
return !annotation.deserialize();
|
||||
}
|
||||
}
|
@ -16,24 +16,23 @@
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
/**
|
||||
* Adapts the old {@link ExclusionStrategy} into the newer {@link ExclusionStrategy2} type.
|
||||
* Excludes fields that do not have the {@link Expose} annotation
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
class ExclusionStrategy2Adapter implements ExclusionStrategy2 {
|
||||
private final ExclusionStrategy strategy;
|
||||
|
||||
public ExclusionStrategy2Adapter(ExclusionStrategy strategy) {
|
||||
Preconditions.checkNotNull(strategy);
|
||||
this.strategy = strategy;
|
||||
public class ExposeAnnotationSerializationExclusionStrategy implements ExclusionStrategy {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
return strategy.shouldSkipClass(clazz);
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
return strategy.shouldSkipField(f);
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
Expose annotation = f.getAnnotation(Expose.class);
|
||||
if (annotation == null) {
|
||||
return true;
|
||||
}
|
||||
return !annotation.serialize();
|
||||
}
|
||||
}
|
@ -90,11 +90,12 @@ public final class Gson {
|
||||
static final FieldNamingStrategy2 DEFAULT_NAMING_POLICY =
|
||||
new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
|
||||
|
||||
private static final ExclusionStrategy2 DEFAULT_EXCLUSION_STRATEGY = createExclusionStrategy();
|
||||
private static final ExclusionStrategy DEFAULT_EXCLUSION_STRATEGY = createExclusionStrategy();
|
||||
|
||||
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
|
||||
|
||||
private final ExclusionStrategy2 exclusionStrategy;
|
||||
private final ExclusionStrategy deserializationExclusionStrategy;
|
||||
private final ExclusionStrategy serializationExclusionStrategy;
|
||||
private final FieldNamingStrategy2 fieldNamingPolicy;
|
||||
private final MappedObjectConstructor objectConstructor;
|
||||
|
||||
@ -144,18 +145,20 @@ public final class Gson {
|
||||
* </ul>
|
||||
*/
|
||||
public Gson() {
|
||||
this(DEFAULT_EXCLUSION_STRATEGY, DEFAULT_NAMING_POLICY,
|
||||
this(DEFAULT_EXCLUSION_STRATEGY, DEFAULT_EXCLUSION_STRATEGY, DEFAULT_NAMING_POLICY,
|
||||
new MappedObjectConstructor(DefaultTypeAdapters.getDefaultInstanceCreators()),
|
||||
false, DefaultTypeAdapters.getAllDefaultSerializers(),
|
||||
DefaultTypeAdapters.getAllDefaultDeserializers(), DEFAULT_JSON_NON_EXECUTABLE, true, false);
|
||||
}
|
||||
|
||||
Gson(ExclusionStrategy2 exclusionStrategy, FieldNamingStrategy2 fieldNamingPolicy,
|
||||
Gson(ExclusionStrategy deserializationExclusionStrategy,
|
||||
ExclusionStrategy serializationExclusionStrategy, FieldNamingStrategy2 fieldNamingPolicy,
|
||||
MappedObjectConstructor objectConstructor, boolean serializeNulls,
|
||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
||||
boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting) {
|
||||
this.exclusionStrategy = exclusionStrategy;
|
||||
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
|
||||
this.serializationExclusionStrategy = serializationExclusionStrategy;
|
||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
||||
this.objectConstructor = objectConstructor;
|
||||
this.serializeNulls = serializeNulls;
|
||||
@ -166,12 +169,12 @@ public final class Gson {
|
||||
this.prettyPrinting = prettyPrinting;
|
||||
}
|
||||
|
||||
private ObjectNavigatorFactory createDefaultObjectNavigatorFactory(ExclusionStrategy2 strategy) {
|
||||
private ObjectNavigatorFactory createDefaultObjectNavigatorFactory(ExclusionStrategy strategy) {
|
||||
return new ObjectNavigatorFactory(strategy, fieldNamingPolicy);
|
||||
}
|
||||
|
||||
private static ExclusionStrategy2 createExclusionStrategy() {
|
||||
List<ExclusionStrategy2> strategies = new LinkedList<ExclusionStrategy2>();
|
||||
private static ExclusionStrategy createExclusionStrategy() {
|
||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||
strategies.add(DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
||||
strategies.add(DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
||||
strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY);
|
||||
@ -219,7 +222,7 @@ public final class Gson {
|
||||
return JsonNull.createJsonNull();
|
||||
}
|
||||
JsonSerializationContextDefault context = new JsonSerializationContextDefault(
|
||||
createDefaultObjectNavigatorFactory(exclusionStrategy), serializeNulls, serializers);
|
||||
createDefaultObjectNavigatorFactory(serializationExclusionStrategy), serializeNulls, serializers);
|
||||
return context.serialize(src, typeOfSrc, true);
|
||||
}
|
||||
|
||||
@ -549,8 +552,8 @@ public final class Gson {
|
||||
return null;
|
||||
}
|
||||
JsonDeserializationContext context = new JsonDeserializationContextDefault(
|
||||
createDefaultObjectNavigatorFactory(exclusionStrategy), deserializers,
|
||||
objectConstructor);
|
||||
createDefaultObjectNavigatorFactory(deserializationExclusionStrategy),
|
||||
deserializers, objectConstructor);
|
||||
T target = (T) context.deserialize(json, typeOfT);
|
||||
return target;
|
||||
}
|
||||
|
@ -18,11 +18,12 @@ package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
|
||||
|
||||
@ -54,11 +55,17 @@ import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
|
||||
public final class GsonBuilder {
|
||||
private static final InnerClassExclusionStrategy innerClassExclusionStrategy =
|
||||
new InnerClassExclusionStrategy();
|
||||
private static final ExposeAnnotationExclusionStrategy exposeAnnotationExclusionStrategy =
|
||||
new ExposeAnnotationExclusionStrategy();
|
||||
private static final ExposeAnnotationDeserializationExclusionStrategy
|
||||
exposeAnnotationDeserializationExclusionStrategy =
|
||||
new ExposeAnnotationDeserializationExclusionStrategy();
|
||||
private static final ExposeAnnotationSerializationExclusionStrategy
|
||||
exposeAnnotationSerializationExclusionStrategy =
|
||||
new ExposeAnnotationSerializationExclusionStrategy();
|
||||
|
||||
private final Collection<ExclusionStrategy2> exclusionStrategies =
|
||||
new HashSet<ExclusionStrategy2>();
|
||||
private final Set<ExclusionStrategy> serializeExclusionStrategies =
|
||||
new HashSet<ExclusionStrategy>();
|
||||
private final Set<ExclusionStrategy> deserializeExclusionStrategies =
|
||||
new HashSet<ExclusionStrategy>();
|
||||
|
||||
private double ignoreVersionsAfter;
|
||||
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
|
||||
@ -86,8 +93,10 @@ public final class GsonBuilder {
|
||||
*/
|
||||
public GsonBuilder() {
|
||||
// add default exclusion strategies
|
||||
exclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
||||
exclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
||||
deserializeExclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
||||
deserializeExclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
||||
serializeExclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
||||
serializeExclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
||||
|
||||
// setup default values
|
||||
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
|
||||
@ -248,32 +257,32 @@ public final class GsonBuilder {
|
||||
* @param strategies the set of strategy object to apply during object (de)serialization.
|
||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||
* @since 1.4
|
||||
* @deprecated convert your {@code strategies} to {@link ExclusionStrategy2} and use the
|
||||
* {@link #setExclusionStrategies(ExclusionStrategy2...) method instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
|
||||
for (ExclusionStrategy strategy : strategies) {
|
||||
exclusionStrategies.add(new ExclusionStrategy2Adapter(strategy));
|
||||
}
|
||||
List<ExclusionStrategy> strategyList = Arrays.asList(strategies);
|
||||
serializeExclusionStrategies.addAll(strategyList);
|
||||
deserializeExclusionStrategies.addAll(strategyList);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Gson to apply a set of exclusion strategies during both serialization and
|
||||
* Configures Gson to apply a set of exclusion strategies during either serialization or
|
||||
* deserialization. Each of the {@code strategies} will be applied as a disjunction rule.
|
||||
* This means that if one of the {@code strategies} suggests that a field (or class) should be
|
||||
* skipped in the current mode then that field (or object) is skipped during the particular Gson
|
||||
* mode.
|
||||
* skipped then that field (or object) is skipped during either serialization or deserialization
|
||||
* depending on the {@code mode} that is passed into this method.
|
||||
*
|
||||
* @param strategies the set of strategy object to apply during object (de)serialization.
|
||||
* @param strategies the set of strategy object to apply during the {@code mode}.
|
||||
* @param the mode of Gson (either serialization or deserialization) as to when the
|
||||
* {@code strategies} should be applied.
|
||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||
* @since 1.7
|
||||
*/
|
||||
public GsonBuilder setExclusionStrategies(ExclusionStrategy2... strategies) {
|
||||
for (ExclusionStrategy2 strategy : strategies) {
|
||||
exclusionStrategies.add(strategy);
|
||||
}
|
||||
public GsonBuilder setExclusionStrategies(Mode mode, ExclusionStrategy... strategies) {
|
||||
Preconditions.checkNotNull(mode);
|
||||
Set<ExclusionStrategy> strategySet = (mode == Mode.SERIALIZE)
|
||||
? serializeExclusionStrategies : deserializeExclusionStrategies;
|
||||
strategySet.addAll(Arrays.asList(strategies));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -519,20 +528,27 @@ public final class GsonBuilder {
|
||||
* @return an instance of Gson configured with the options currently set in this builder
|
||||
*/
|
||||
public Gson create() {
|
||||
List<ExclusionStrategy2> strategies =
|
||||
new LinkedList<ExclusionStrategy2>(exclusionStrategies);
|
||||
strategies.add(modifierBasedExclusionStrategy);
|
||||
List<ExclusionStrategy> deserializationStrategies =
|
||||
new LinkedList<ExclusionStrategy>(deserializeExclusionStrategies);
|
||||
List<ExclusionStrategy> serializationStrategies =
|
||||
new LinkedList<ExclusionStrategy>(serializeExclusionStrategies);
|
||||
deserializationStrategies.add(modifierBasedExclusionStrategy);
|
||||
serializationStrategies.add(modifierBasedExclusionStrategy);
|
||||
|
||||
if (!serializeInnerClasses) {
|
||||
strategies.add(innerClassExclusionStrategy);
|
||||
deserializationStrategies.add(innerClassExclusionStrategy);
|
||||
serializationStrategies.add(innerClassExclusionStrategy);
|
||||
}
|
||||
if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
|
||||
strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
||||
VersionExclusionStrategy versionExclusionStrategy =
|
||||
new VersionExclusionStrategy(ignoreVersionsAfter);
|
||||
deserializationStrategies.add(versionExclusionStrategy);
|
||||
serializationStrategies.add(versionExclusionStrategy);
|
||||
}
|
||||
if (excludeFieldsWithoutExposeAnnotation) {
|
||||
strategies.add(exposeAnnotationExclusionStrategy);
|
||||
deserializationStrategies.add(exposeAnnotationDeserializationExclusionStrategy);
|
||||
serializationStrategies.add(exposeAnnotationSerializationExclusionStrategy);
|
||||
}
|
||||
ExclusionStrategy2 exclusionStrategy = new DisjunctionExclusionStrategy(strategies);
|
||||
|
||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers =
|
||||
DefaultTypeAdapters.DEFAULT_HIERARCHY_SERIALIZERS.copyOf();
|
||||
@ -558,7 +574,9 @@ public final class GsonBuilder {
|
||||
|
||||
MappedObjectConstructor objConstructor = new MappedObjectConstructor(customInstanceCreators);
|
||||
|
||||
Gson gson = new Gson(exclusionStrategy, fieldNamingPolicy, objConstructor, serializeNulls,
|
||||
Gson gson = new Gson(new DisjunctionExclusionStrategy(deserializationStrategies),
|
||||
new DisjunctionExclusionStrategy(serializationStrategies),
|
||||
fieldNamingPolicy, objConstructor, serializeNulls,
|
||||
customSerializers, customDeserializers, generateNonExecutableJson, escapeHtmlChars,
|
||||
prettyPrinting);
|
||||
return gson;
|
||||
|
@ -23,13 +23,13 @@ import java.lang.reflect.Modifier;
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
class InnerClassExclusionStrategy implements ExclusionStrategy2 {
|
||||
class InnerClassExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return isInnerClass(f.getDeclaredClass());
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return isInnerClass(clazz);
|
||||
}
|
||||
|
||||
|
@ -58,10 +58,6 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
public Mode getMode() {
|
||||
return Mode.DESERIALIZE;
|
||||
}
|
||||
|
||||
protected abstract T constructTarget();
|
||||
|
||||
|
@ -47,10 +47,6 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
public Object getTarget() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Mode getMode() {
|
||||
return Mode.SERIALIZE;
|
||||
}
|
||||
|
||||
public void start(ObjectTypePair node) {
|
||||
if (node == null) {
|
||||
|
@ -26,7 +26,7 @@ import java.util.HashSet;
|
||||
* @author Inderjeet Singh
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class ModifierBasedExclusionStrategy implements ExclusionStrategy2 {
|
||||
final class ModifierBasedExclusionStrategy implements ExclusionStrategy {
|
||||
private final Collection<Integer> modifiers;
|
||||
|
||||
public ModifierBasedExclusionStrategy(int... modifiers) {
|
||||
@ -38,7 +38,7 @@ final class ModifierBasedExclusionStrategy implements ExclusionStrategy2 {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
for (int modifier : modifiers) {
|
||||
if (f.hasModifier(modifier)) {
|
||||
return true;
|
||||
@ -47,7 +47,7 @@ final class ModifierBasedExclusionStrategy implements ExclusionStrategy2 {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,13 @@ package com.google.gson;
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class NullExclusionStrategy implements ExclusionStrategy2 {
|
||||
final class NullExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -75,11 +75,9 @@ final class ObjectNavigator {
|
||||
* Retrieve the current target
|
||||
*/
|
||||
Object getTarget();
|
||||
|
||||
Mode getMode();
|
||||
}
|
||||
|
||||
private final ExclusionStrategy2 exclusionStrategy;
|
||||
private final ExclusionStrategy exclusionStrategy;
|
||||
private final ObjectTypePair objTypePair;
|
||||
|
||||
/**
|
||||
@ -89,7 +87,7 @@ final class ObjectNavigator {
|
||||
* the concrete strategy object to be used to filter out fields of an
|
||||
* object.
|
||||
*/
|
||||
ObjectNavigator(ObjectTypePair objTypePair, ExclusionStrategy2 exclusionStrategy) {
|
||||
ObjectNavigator(ObjectTypePair objTypePair, ExclusionStrategy exclusionStrategy) {
|
||||
Preconditions.checkNotNull(exclusionStrategy);
|
||||
|
||||
this.objTypePair = objTypePair;
|
||||
@ -101,7 +99,7 @@ final class ObjectNavigator {
|
||||
* does not get visited.
|
||||
*/
|
||||
public void accept(Visitor visitor) {
|
||||
if (exclusionStrategy.shouldSkipClass(Types.getRawType(objTypePair.type), visitor.getMode())) {
|
||||
if (exclusionStrategy.shouldSkipClass(Types.getRawType(objTypePair.type))) {
|
||||
return;
|
||||
}
|
||||
boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(objTypePair);
|
||||
@ -145,13 +143,12 @@ final class ObjectNavigator {
|
||||
}
|
||||
|
||||
private void navigateClassFields(Object obj, Class<?> clazz, Visitor visitor) {
|
||||
Mode mode = visitor.getMode();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
AccessibleObject.setAccessible(fields, true);
|
||||
for (Field f : fields) {
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
||||
if (exclusionStrategy.shouldSkipField(fieldAttributes, mode)
|
||||
|| exclusionStrategy.shouldSkipClass(fieldAttributes.getDeclaredClass(), mode)) {
|
||||
if (exclusionStrategy.shouldSkipField(fieldAttributes)
|
||||
|| exclusionStrategy.shouldSkipClass(fieldAttributes.getDeclaredClass())) {
|
||||
continue; // skip
|
||||
}
|
||||
Type declaredTypeOfField = getTypeInfoForField(f, objTypePair.type);
|
||||
|
@ -24,7 +24,7 @@ package com.google.gson;
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class ObjectNavigatorFactory {
|
||||
private final ExclusionStrategy2 strategy;
|
||||
private final ExclusionStrategy strategy;
|
||||
private final FieldNamingStrategy2 fieldNamingPolicy;
|
||||
|
||||
/**
|
||||
@ -36,7 +36,7 @@ final class ObjectNavigatorFactory {
|
||||
* @param fieldNamingPolicy the naming policy that should be applied to field
|
||||
* names
|
||||
*/
|
||||
public ObjectNavigatorFactory(ExclusionStrategy2 strategy, FieldNamingStrategy2 fieldNamingPolicy) {
|
||||
public ObjectNavigatorFactory(ExclusionStrategy strategy, FieldNamingStrategy2 fieldNamingPolicy) {
|
||||
Preconditions.checkNotNull(fieldNamingPolicy);
|
||||
this.strategy = (strategy == null ? new NullExclusionStrategy() : strategy);
|
||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
||||
|
@ -26,18 +26,18 @@ package com.google.gson;
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class SyntheticFieldExclusionStrategy implements ExclusionStrategy2 {
|
||||
class SyntheticFieldExclusionStrategy implements ExclusionStrategy {
|
||||
private final boolean skipSyntheticFields;
|
||||
|
||||
SyntheticFieldExclusionStrategy(boolean skipSyntheticFields) {
|
||||
this.skipSyntheticFields = skipSyntheticFields;
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return skipSyntheticFields && f.isSynthetic();
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import com.google.gson.annotations.Until;
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class VersionExclusionStrategy implements ExclusionStrategy2 {
|
||||
final class VersionExclusionStrategy implements ExclusionStrategy {
|
||||
private final double version;
|
||||
|
||||
public VersionExclusionStrategy(double version) {
|
||||
@ -33,11 +33,11 @@ final class VersionExclusionStrategy implements ExclusionStrategy2 {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return !isValidVersion(f.getAnnotation(Since.class), f.getAnnotation(Until.class));
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return !isValidVersion(clazz.getAnnotation(Since.class), clazz.getAnnotation(Until.class));
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,11 @@
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link DisjunctionExclusionStrategy} class.
|
||||
*
|
||||
@ -28,38 +28,38 @@ import junit.framework.TestCase;
|
||||
*/
|
||||
public class DisjunctionExclusionStrategyTest extends TestCase {
|
||||
|
||||
private static final ExclusionStrategy2 FALSE_STRATEGY =
|
||||
new MockExclusionStrategy2(false, false, null);
|
||||
private static final ExclusionStrategy2 TRUE_STRATEGY =
|
||||
new MockExclusionStrategy2(true, true, null);
|
||||
private static final ExclusionStrategy FALSE_STRATEGY =
|
||||
new MockExclusionStrategy(false, false);
|
||||
private static final ExclusionStrategy TRUE_STRATEGY =
|
||||
new MockExclusionStrategy(true, true);
|
||||
|
||||
private static final Class<?> CLAZZ = String.class;
|
||||
private static final FieldAttributes FIELD = new FieldAttributes(CLAZZ, CLAZZ.getFields()[0]);
|
||||
|
||||
public void testBadInstantiation() throws Exception {
|
||||
try {
|
||||
List<ExclusionStrategy2> constructorParam = null;
|
||||
List<ExclusionStrategy> constructorParam = null;
|
||||
new DisjunctionExclusionStrategy(constructorParam);
|
||||
fail("Should throw an exception");
|
||||
} catch (IllegalArgumentException expected) { }
|
||||
}
|
||||
|
||||
public void testSkipFieldsWithMixedTrueAndFalse() throws Exception {
|
||||
List<ExclusionStrategy2> strategies = new LinkedList<ExclusionStrategy2>();
|
||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||
strategies.add(FALSE_STRATEGY);
|
||||
strategies.add(TRUE_STRATEGY);
|
||||
DisjunctionExclusionStrategy strategy = new DisjunctionExclusionStrategy(strategies);
|
||||
|
||||
assertTrue(strategy.shouldSkipClass(CLAZZ, Mode.SERIALIZE));
|
||||
assertTrue(strategy.shouldSkipField(FIELD, Mode.SERIALIZE));
|
||||
assertTrue(strategy.shouldSkipClass(CLAZZ));
|
||||
assertTrue(strategy.shouldSkipField(FIELD));
|
||||
}
|
||||
|
||||
public void testSkipFieldsWithFalseOnly() throws Exception {
|
||||
List<ExclusionStrategy2> strategies = new LinkedList<ExclusionStrategy2>();
|
||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||
strategies.add(FALSE_STRATEGY);
|
||||
DisjunctionExclusionStrategy strategy = new DisjunctionExclusionStrategy(strategies);
|
||||
|
||||
assertFalse(strategy.shouldSkipClass(CLAZZ, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(FIELD, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(CLAZZ));
|
||||
assertFalse(strategy.shouldSkipField(FIELD));
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Unit test for the {@link ExclusionStrategy2Adapter} class.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public class ExclusionStrategy2AdapterTest extends TestCase {
|
||||
|
||||
public void testConstruction() throws Exception {
|
||||
try {
|
||||
new ExclusionStrategy2Adapter(null);
|
||||
fail();
|
||||
} catch (IllegalArgumentException expected) {}
|
||||
}
|
||||
|
||||
public void testAdapterDoesSameForBothModes() throws Exception {
|
||||
ExclusionStrategy2Adapter adapter =
|
||||
new ExclusionStrategy2Adapter(new MockExclusionStrategy(true, false));
|
||||
assertTrue(adapter.shouldSkipClass(String.class, Mode.DESERIALIZE));
|
||||
assertTrue(adapter.shouldSkipClass(String.class, Mode.SERIALIZE));
|
||||
|
||||
Field f = String.class.getFields()[0];
|
||||
assertFalse(adapter.shouldSkipField(new FieldAttributes(String.class, f), Mode.DESERIALIZE));
|
||||
assertFalse(adapter.shouldSkipField(new FieldAttributes(String.class, f), Mode.SERIALIZE));
|
||||
}
|
||||
}
|
@ -16,59 +16,61 @@
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link ExposeAnnotationExclusionStrategy} class.
|
||||
* Unit tests for the {@link ExposeAnnotationSerializationExclusionStrategy} class.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public class ExposeAnnotationExclusionStrategyTest extends TestCase {
|
||||
private ExposeAnnotationExclusionStrategy strategy;
|
||||
private ExposeAnnotationDeserializationExclusionStrategy deserializationStrategy;
|
||||
private ExposeAnnotationSerializationExclusionStrategy serializationStrategy;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
strategy = new ExposeAnnotationExclusionStrategy();
|
||||
deserializationStrategy = new ExposeAnnotationDeserializationExclusionStrategy();
|
||||
serializationStrategy = new ExposeAnnotationSerializationExclusionStrategy();
|
||||
}
|
||||
|
||||
public void testNeverSkipClasses() throws Exception {
|
||||
assertFalse(strategy.shouldSkipClass(MockObject.class, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(MockObject.class, Mode.SERIALIZE));
|
||||
assertFalse(deserializationStrategy.shouldSkipClass(MockObject.class));
|
||||
assertFalse(serializationStrategy.shouldSkipClass(MockObject.class));
|
||||
}
|
||||
|
||||
public void testSkipNonAnnotatedFields() throws Exception {
|
||||
FieldAttributes f = createFieldAttributes("hiddenField");
|
||||
assertTrue(strategy.shouldSkipField(f, Mode.DESERIALIZE));
|
||||
assertTrue(strategy.shouldSkipField(f, Mode.SERIALIZE));
|
||||
assertTrue(deserializationStrategy.shouldSkipField(f));
|
||||
assertTrue(serializationStrategy.shouldSkipField(f));
|
||||
}
|
||||
|
||||
public void testSkipExplicitlySkippedFields() throws Exception {
|
||||
FieldAttributes f = createFieldAttributes("explicitlyHiddenField");
|
||||
assertTrue(strategy.shouldSkipField(f, Mode.DESERIALIZE));
|
||||
assertTrue(strategy.shouldSkipField(f, Mode.SERIALIZE));
|
||||
assertTrue(deserializationStrategy.shouldSkipField(f));
|
||||
assertTrue(serializationStrategy.shouldSkipField(f));
|
||||
}
|
||||
|
||||
public void testNeverSkipExposedAnnotatedFields() throws Exception {
|
||||
FieldAttributes f = createFieldAttributes("exposedField");
|
||||
assertFalse(strategy.shouldSkipField(f, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(f, Mode.SERIALIZE));
|
||||
assertFalse(deserializationStrategy.shouldSkipField(f));
|
||||
assertFalse(serializationStrategy.shouldSkipField(f));
|
||||
}
|
||||
|
||||
public void testNeverSkipExplicitlyExposedAnnotatedFields() throws Exception {
|
||||
FieldAttributes f = createFieldAttributes("explicitlyExposedField");
|
||||
assertFalse(strategy.shouldSkipField(f, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(f, Mode.SERIALIZE));
|
||||
assertFalse(deserializationStrategy.shouldSkipField(f));
|
||||
assertFalse(serializationStrategy.shouldSkipField(f));
|
||||
}
|
||||
|
||||
public void testDifferentSerializeAndDeserializeField() throws Exception {
|
||||
FieldAttributes f = createFieldAttributes("explicitlyDifferentModeField");
|
||||
assertTrue(strategy.shouldSkipField(f, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(f, Mode.SERIALIZE));
|
||||
assertTrue(deserializationStrategy.shouldSkipField(f));
|
||||
assertFalse(serializationStrategy.shouldSkipField(f));
|
||||
}
|
||||
|
||||
private static FieldAttributes createFieldAttributes(String fieldName) throws Exception {
|
||||
|
@ -35,11 +35,11 @@ import com.google.gson.common.TestTypes.ClassWithNoFields;
|
||||
public class FunctionWithInternalDependenciesTest extends TestCase {
|
||||
|
||||
public void testAnonymousLocalClassesSerialization() throws Exception {
|
||||
LinkedList<ExclusionStrategy2> strategies = new LinkedList<ExclusionStrategy2>();
|
||||
LinkedList<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||
strategies.add(new SyntheticFieldExclusionStrategy(true));
|
||||
strategies.add(new ModifierBasedExclusionStrategy(Modifier.TRANSIENT, Modifier.STATIC));
|
||||
ExclusionStrategy2 exclusionStrategy = new DisjunctionExclusionStrategy(strategies);
|
||||
Gson gson = new Gson(exclusionStrategy, Gson.DEFAULT_NAMING_POLICY,
|
||||
ExclusionStrategy exclusionStrategy = new DisjunctionExclusionStrategy(strategies);
|
||||
Gson gson = new Gson(exclusionStrategy, exclusionStrategy, Gson.DEFAULT_NAMING_POLICY,
|
||||
new MappedObjectConstructor(DefaultTypeAdapters.getDefaultInstanceCreators()),
|
||||
false, DefaultTypeAdapters.getDefaultSerializers(),
|
||||
DefaultTypeAdapters.getDefaultDeserializers(), Gson.DEFAULT_JSON_NON_EXECUTABLE, true,
|
||||
@ -48,32 +48,4 @@ public class FunctionWithInternalDependenciesTest extends TestCase {
|
||||
// empty anonymous class
|
||||
}));
|
||||
}
|
||||
|
||||
// TODO(Joel): Move this to some other functional test once exclusion policies are
|
||||
// available to the public
|
||||
public void testUserDefinedExclusionPolicies() throws Exception {
|
||||
Gson gson = new GsonBuilder()
|
||||
.setExclusionStrategies(new UserDefinedExclusionStrategy(String.class))
|
||||
.create();
|
||||
|
||||
String json = gson.toJson(new TestTypes.StringWrapper("someValue"));
|
||||
assertEquals("{}", json);
|
||||
}
|
||||
|
||||
private static class UserDefinedExclusionStrategy implements ExclusionStrategy2 {
|
||||
private final Class<?> excludedThisClass;
|
||||
|
||||
UserDefinedExclusionStrategy(Class<?> excludedThisClass) {
|
||||
this.excludedThisClass = excludedThisClass;
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
return excludedThisClass.equals(clazz);
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
return excludedThisClass.equals(f.getDeclaredClass());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,10 @@
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Unit test for the {@link InnerClassExclusionStrategy} class.
|
||||
*
|
||||
@ -41,26 +41,22 @@ public class InnerClassExclusionStrategyTest extends TestCase {
|
||||
|
||||
public void testExcludeInnerClassObject() throws Exception {
|
||||
Class<?> clazz = innerClass.getClass();
|
||||
assertTrue(strategy.shouldSkipClass(clazz, Mode.SERIALIZE));
|
||||
assertTrue(strategy.shouldSkipClass(clazz, Mode.DESERIALIZE));
|
||||
assertTrue(strategy.shouldSkipClass(clazz));
|
||||
}
|
||||
|
||||
public void testExcludeInnerClassField() throws Exception {
|
||||
Field f = getClass().getField("innerClass");
|
||||
assertTrue(strategy.shouldSkipField(new FieldAttributes(getClass(), f), Mode.SERIALIZE));
|
||||
assertTrue(strategy.shouldSkipField(new FieldAttributes(getClass(), f), Mode.DESERIALIZE));
|
||||
assertTrue(strategy.shouldSkipField(new FieldAttributes(getClass(), f)));
|
||||
}
|
||||
|
||||
public void testIncludeStaticNestedClassObject() throws Exception {
|
||||
Class<?> clazz = staticNestedClass.getClass();
|
||||
assertFalse(strategy.shouldSkipClass(clazz, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(clazz, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(clazz));
|
||||
}
|
||||
|
||||
public void testIncludeStaticNestedClassField() throws Exception {
|
||||
Field f = getClass().getField("staticNestedClass");
|
||||
assertFalse(strategy.shouldSkipField(new FieldAttributes(getClass(), f), Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(new FieldAttributes(getClass(), f), Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(new FieldAttributes(getClass(), f)));
|
||||
}
|
||||
|
||||
class InnerClass {
|
||||
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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;
|
||||
|
||||
/**
|
||||
* This is a configurable {@link ExclusionStrategy2} that can be used for
|
||||
* unit testing.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public class MockExclusionStrategy2 implements ExclusionStrategy2 {
|
||||
private final MockExclusionStrategy strategy;
|
||||
private final Mode mode;
|
||||
|
||||
public MockExclusionStrategy2(boolean skipClass, boolean skipField, Mode mode) {
|
||||
this.strategy = new MockExclusionStrategy(skipClass, skipField);
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f, Mode mode) {
|
||||
if (this.mode == null || this.mode == mode) {
|
||||
return strategy.shouldSkipField(f);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz, Mode mode) {
|
||||
if (this.mode == null || this.mode == mode) {
|
||||
return strategy.shouldSkipClass(clazz);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -33,16 +33,11 @@ public class NullExclusionStrategyTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testNeverSkipsClass() throws Exception {
|
||||
assertFalse(strategy.shouldSkipClass(String.class, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(String.class, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(String.class));
|
||||
}
|
||||
|
||||
public void testNeverSkipsField() throws Exception {
|
||||
assertFalse(strategy.shouldSkipField(
|
||||
new FieldAttributes(String.class, String.class.getFields()[0]),
|
||||
Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(
|
||||
new FieldAttributes(String.class, String.class.getFields()[0]),
|
||||
Mode.DESERIALIZE));
|
||||
new FieldAttributes(String.class, String.class.getFields()[0])));
|
||||
}
|
||||
}
|
||||
|
@ -41,39 +41,30 @@ public class VersionExclusionStrategyTest extends TestCase {
|
||||
Class<MockObject> clazz = MockObject.class;
|
||||
Field f = clazz.getField("someField");
|
||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION);
|
||||
|
||||
assertFalse(strategy.shouldSkipClass(clazz, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(clazz, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(clazz));
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
||||
}
|
||||
|
||||
public void testClassAndFieldAreBehindInVersion() throws Exception {
|
||||
Class<MockObject> clazz = MockObject.class;
|
||||
Field f = clazz.getField("someField");
|
||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION + 1);
|
||||
|
||||
assertFalse(strategy.shouldSkipClass(clazz, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(clazz, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipClass(clazz));
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes, Mode.DESERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes, Mode.SERIALIZE));
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
||||
}
|
||||
|
||||
public void testClassAndFieldAreAheadInVersion() throws Exception {
|
||||
Class<MockObject> clazz = MockObject.class;
|
||||
Field f = clazz.getField("someField");
|
||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION - 1);
|
||||
|
||||
assertTrue(strategy.shouldSkipClass(clazz, Mode.DESERIALIZE));
|
||||
assertTrue(strategy.shouldSkipClass(clazz, Mode.SERIALIZE));
|
||||
assertTrue(strategy.shouldSkipClass(clazz));
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
||||
assertTrue(strategy.shouldSkipField(fieldAttributes, Mode.DESERIALIZE));
|
||||
assertTrue(strategy.shouldSkipField(fieldAttributes, Mode.SERIALIZE));
|
||||
assertTrue(strategy.shouldSkipField(fieldAttributes));
|
||||
}
|
||||
|
||||
@Since(VERSION)
|
||||
|
@ -17,14 +17,11 @@
|
||||
package com.google.gson.functional;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.ExclusionStrategy2;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.MockExclusionStrategy;
|
||||
import com.google.gson.MockExclusionStrategy2;
|
||||
import com.google.gson.Mode;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@ -43,41 +40,23 @@ import java.lang.annotation.Target;
|
||||
*/
|
||||
public class ExclusionStrategyFunctionalTest extends TestCase {
|
||||
private SampleObjectForTest src;
|
||||
private Gson gson;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
gson = new GsonBuilder()
|
||||
.setExclusionStrategies(new MyExclusionStrategy(String.class))
|
||||
.serializeNulls()
|
||||
.create();
|
||||
src = new SampleObjectForTest();
|
||||
}
|
||||
|
||||
public void testExclusionStrategySerialization() throws Exception {
|
||||
Gson gson = createGson(new MyExclusionStrategy(String.class));
|
||||
Gson gson = createGson(new MyExclusionStrategy(String.class), null);
|
||||
String json = gson.toJson(src);
|
||||
assertFalse(json.contains("\"stringField\""));
|
||||
assertFalse(json.contains("\"annotatedField\""));
|
||||
assertTrue(json.contains("\"longField\""));
|
||||
}
|
||||
|
||||
public void testExclusionStrategy2Serialization() throws Exception {
|
||||
Gson gson = createGson(new MockExclusionStrategy2(false, true, Mode.DESERIALIZE));
|
||||
String json = gson.toJson(src);
|
||||
assertTrue(json.contains("\"stringField\""));
|
||||
assertTrue(json.contains("\"annotatedField\""));
|
||||
assertTrue(json.contains("\"longField\""));
|
||||
|
||||
gson = createGson(new MockExclusionStrategy2(false, true, Mode.SERIALIZE));
|
||||
json = gson.toJson(src);
|
||||
assertFalse(json.contains("\"stringField\""));
|
||||
assertFalse(json.contains("\"annotatedField\""));
|
||||
assertFalse(json.contains("\"longField\""));
|
||||
}
|
||||
|
||||
public void testExclusionStrategyDeserialization() throws Exception {
|
||||
Gson gson = createGson(new MyExclusionStrategy(String.class), null);
|
||||
JsonObject json = new JsonObject();
|
||||
json.add("annotatedField", new JsonPrimitive(src.annotatedField + 5));
|
||||
json.add("stringField", new JsonPrimitive(src.stringField + "blah,blah"));
|
||||
@ -90,17 +69,34 @@ public class ExclusionStrategyFunctionalTest extends TestCase {
|
||||
assertEquals(src.annotatedField, target.annotatedField);
|
||||
assertEquals(src.stringField, target.stringField);
|
||||
}
|
||||
|
||||
private static Gson createGson(ExclusionStrategy exclusionStrategy) {
|
||||
return new GsonBuilder()
|
||||
.setExclusionStrategies(exclusionStrategy)
|
||||
.serializeNulls()
|
||||
.create();
|
||||
}
|
||||
|
||||
private static Gson createGson(ExclusionStrategy2 exclusionStrategy) {
|
||||
return new GsonBuilder()
|
||||
.setExclusionStrategies(exclusionStrategy)
|
||||
public void testExclusionStrategyWithMode() throws Exception {
|
||||
SampleObjectForTest testObj = new SampleObjectForTest(
|
||||
src.annotatedField + 5, src.stringField + "blah,blah",
|
||||
src.longField + 655L);
|
||||
|
||||
Gson gson = createGson(new MyExclusionStrategy(String.class), Mode.DESERIALIZE);
|
||||
JsonObject json = gson.toJsonTree(testObj).getAsJsonObject();
|
||||
assertEquals(testObj.annotatedField, json.get("annotatedField").getAsInt());
|
||||
assertEquals(testObj.stringField, json.get("stringField").getAsString());
|
||||
assertEquals(testObj.longField, json.get("longField").getAsLong());
|
||||
|
||||
SampleObjectForTest target = gson.fromJson(json, SampleObjectForTest.class);
|
||||
assertEquals(testObj.longField, target.longField);
|
||||
|
||||
// assert excluded fields are set to the defaults
|
||||
assertEquals(src.annotatedField, target.annotatedField);
|
||||
assertEquals(src.stringField, target.stringField);
|
||||
}
|
||||
|
||||
private static Gson createGson(ExclusionStrategy exclusionStrategy, Mode mode) {
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
if (mode == null) {
|
||||
gsonBuilder.setExclusionStrategies(exclusionStrategy);
|
||||
} else {
|
||||
gsonBuilder.setExclusionStrategies(mode, exclusionStrategy);
|
||||
}
|
||||
return gsonBuilder
|
||||
.serializeNulls()
|
||||
.create();
|
||||
}
|
||||
@ -117,13 +113,15 @@ public class ExclusionStrategyFunctionalTest extends TestCase {
|
||||
private final int annotatedField;
|
||||
private final String stringField;
|
||||
private final long longField;
|
||||
private final Class<?> clazzField;
|
||||
|
||||
public SampleObjectForTest() {
|
||||
annotatedField = 5;
|
||||
stringField = "someDefaultValue";
|
||||
longField = 1234;
|
||||
clazzField = String.class;
|
||||
this(5, "someDefaultValue", 12345L);
|
||||
}
|
||||
|
||||
public SampleObjectForTest(int annotatedField, String stringField, long longField) {
|
||||
this.annotatedField = annotatedField;
|
||||
this.stringField = stringField;
|
||||
this.longField = longField;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user