Begin to tighten the ExclusionStrategy code. This replaces named classes with anonymous classes wherever we have a single instance of a type.
This commit is contained in:
parent
e23973afec
commit
7def596775
@ -1,38 +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;
|
||||
|
||||
/**
|
||||
* Strategy for excluding anonymous and local classes.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class AnonymousAndLocalClassExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return isAnonymousOrLocal(f.getDeclaredClass());
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return isAnonymousOrLocal(clazz);
|
||||
}
|
||||
|
||||
private boolean isAnonymousOrLocal(Class<?> clazz) {
|
||||
return !Enum.class.isAssignableFrom(clazz)
|
||||
&& (clazz.isAnonymousClass() || clazz.isLocalClass());
|
||||
}
|
||||
}
|
@ -1,38 +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 com.google.gson.annotations.Expose;
|
||||
|
||||
/**
|
||||
* Excludes fields that do not have the {@link Expose} annotation
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class ExposeAnnotationDeserializationExclusionStrategy implements ExclusionStrategy {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
Expose annotation = f.getAnnotation(Expose.class);
|
||||
if (annotation == null) {
|
||||
return true;
|
||||
}
|
||||
return !annotation.deserialize();
|
||||
}
|
||||
}
|
@ -1,38 +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 com.google.gson.annotations.Expose;
|
||||
|
||||
/**
|
||||
* Excludes fields that do not have the {@link Expose} annotation
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class ExposeAnnotationSerializationExclusionStrategy implements ExclusionStrategy {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
Expose annotation = f.getAnnotation(Expose.class);
|
||||
if (annotation == null) {
|
||||
return true;
|
||||
}
|
||||
return !annotation.serialize();
|
||||
}
|
||||
}
|
@ -45,7 +45,6 @@ import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
@ -104,14 +103,6 @@ public final class Gson {
|
||||
|
||||
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
|
||||
|
||||
// Default instances of plug-ins
|
||||
static final AnonymousAndLocalClassExclusionStrategy DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY =
|
||||
new AnonymousAndLocalClassExclusionStrategy();
|
||||
static final SyntheticFieldExclusionStrategy DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY =
|
||||
new SyntheticFieldExclusionStrategy(true);
|
||||
static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
|
||||
new ModifierBasedExclusionStrategy(Modifier.TRANSIENT, Modifier.STATIC);
|
||||
|
||||
private static final ExclusionStrategy DEFAULT_EXCLUSION_STRATEGY = createExclusionStrategy();
|
||||
|
||||
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
|
||||
@ -352,9 +343,9 @@ public final class Gson {
|
||||
|
||||
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);
|
||||
strategies.add(GsonBuilder.EXCLUDE_ANONYMOUS_AND_LOCAL);
|
||||
strategies.add(GsonBuilder.EXCLUDE_SYNTHETIC_FIELDS);
|
||||
strategies.add(GsonBuilder.EXCLUDE_TRANSIENT_AND_STATIC);
|
||||
return new DisjunctionExclusionStrategy(strategies);
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,13 @@
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.internal.$Gson$Preconditions;
|
||||
import com.google.gson.internal.Primitives;
|
||||
import com.google.gson.internal.TypeMap;
|
||||
import com.google.gson.internal.bind.TypeAdapters;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
@ -67,14 +69,68 @@ import java.util.Set;
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public final class GsonBuilder {
|
||||
private static final InnerClassExclusionStrategy innerClassExclusionStrategy =
|
||||
new InnerClassExclusionStrategy();
|
||||
private static final ExposeAnnotationDeserializationExclusionStrategy
|
||||
exposeAnnotationDeserializationExclusionStrategy =
|
||||
new ExposeAnnotationDeserializationExclusionStrategy();
|
||||
private static final ExposeAnnotationSerializationExclusionStrategy
|
||||
exposeAnnotationSerializationExclusionStrategy =
|
||||
new ExposeAnnotationSerializationExclusionStrategy();
|
||||
/** Strategy for excluding inner classes. */
|
||||
static final ExclusionStrategy EXCLUDE_INNER_CLASSES = new ExclusionStrategy() {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return isInnerClass(f.getDeclaredClass());
|
||||
}
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return isInnerClass(clazz);
|
||||
}
|
||||
private boolean isInnerClass(Class<?> clazz) {
|
||||
return clazz.isMemberClass() && !isStatic(clazz);
|
||||
}
|
||||
private boolean isStatic(Class<?> clazz) {
|
||||
return (clazz.getModifiers() & Modifier.STATIC) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** Excludes fields that do not have the {@link Expose} annotation */
|
||||
static final ExclusionStrategy REQUIRE_EXPOSE_DESERIALIZE = new ExclusionStrategy() {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
Expose annotation = f.getAnnotation(Expose.class);
|
||||
return annotation == null || !annotation.deserialize();
|
||||
}
|
||||
};
|
||||
|
||||
/** Excludes fields that do not have the {@link Expose} annotation */
|
||||
static final ExclusionStrategy REQUIRE_EXPOSE_SERIALIZE = new ExclusionStrategy() {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
Expose annotation = f.getAnnotation(Expose.class);
|
||||
return annotation == null || !annotation.serialize();
|
||||
}
|
||||
};
|
||||
|
||||
static final ExclusionStrategy EXCLUDE_ANONYMOUS_AND_LOCAL = new ExclusionStrategy() {
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return isAnonymousOrLocal(f.getDeclaredClass());
|
||||
}
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return isAnonymousOrLocal(clazz);
|
||||
}
|
||||
private boolean isAnonymousOrLocal(Class<?> clazz) {
|
||||
return !Enum.class.isAssignableFrom(clazz)
|
||||
&& (clazz.isAnonymousClass() || clazz.isLocalClass());
|
||||
}
|
||||
};
|
||||
|
||||
static final ExclusionStrategy EXCLUDE_SYNTHETIC_FIELDS = new ExclusionStrategy() {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return f.isSynthetic();
|
||||
}
|
||||
};
|
||||
|
||||
static final ModifierBasedExclusionStrategy EXCLUDE_TRANSIENT_AND_STATIC
|
||||
= new ModifierBasedExclusionStrategy(Modifier.TRANSIENT, Modifier.STATIC);
|
||||
|
||||
private final Set<ExclusionStrategy> serializeExclusionStrategies =
|
||||
new HashSet<ExclusionStrategy>();
|
||||
@ -110,17 +166,17 @@ public final class GsonBuilder {
|
||||
*/
|
||||
public GsonBuilder() {
|
||||
// add default exclusion strategies
|
||||
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);
|
||||
deserializeExclusionStrategies.add(EXCLUDE_ANONYMOUS_AND_LOCAL);
|
||||
deserializeExclusionStrategies.add(EXCLUDE_SYNTHETIC_FIELDS);
|
||||
serializeExclusionStrategies.add(EXCLUDE_ANONYMOUS_AND_LOCAL);
|
||||
serializeExclusionStrategies.add(EXCLUDE_SYNTHETIC_FIELDS);
|
||||
|
||||
// setup default values
|
||||
ignoreVersionsAfter = VersionExclusionStrategy.IGNORE_VERSIONS;
|
||||
serializeInnerClasses = true;
|
||||
prettyPrinting = false;
|
||||
escapeHtmlChars = true;
|
||||
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
|
||||
modifierBasedExclusionStrategy = EXCLUDE_TRANSIENT_AND_STATIC;
|
||||
excludeFieldsWithoutExposeAnnotation = false;
|
||||
longSerializationPolicy = LongSerializationPolicy.DEFAULT;
|
||||
fieldNamingPolicy = FieldNamingPolicy.IDENTITY;
|
||||
@ -636,8 +692,8 @@ public final class GsonBuilder {
|
||||
serializationStrategies.add(modifierBasedExclusionStrategy);
|
||||
|
||||
if (!serializeInnerClasses) {
|
||||
deserializationStrategies.add(innerClassExclusionStrategy);
|
||||
serializationStrategies.add(innerClassExclusionStrategy);
|
||||
deserializationStrategies.add(EXCLUDE_INNER_CLASSES);
|
||||
serializationStrategies.add(EXCLUDE_INNER_CLASSES);
|
||||
}
|
||||
if (ignoreVersionsAfter != VersionExclusionStrategy.IGNORE_VERSIONS) {
|
||||
VersionExclusionStrategy versionExclusionStrategy =
|
||||
@ -646,8 +702,8 @@ public final class GsonBuilder {
|
||||
serializationStrategies.add(versionExclusionStrategy);
|
||||
}
|
||||
if (excludeFieldsWithoutExposeAnnotation) {
|
||||
deserializationStrategies.add(exposeAnnotationDeserializationExclusionStrategy);
|
||||
serializationStrategies.add(exposeAnnotationSerializationExclusionStrategy);
|
||||
deserializationStrategies.add(REQUIRE_EXPOSE_DESERIALIZE);
|
||||
serializationStrategies.add(REQUIRE_EXPOSE_SERIALIZE);
|
||||
}
|
||||
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, serializers, deserializers);
|
||||
|
||||
|
@ -1,43 +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;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* Strategy for excluding inner classes.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class InnerClassExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return isInnerClass(f.getDeclaredClass());
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return isInnerClass(clazz);
|
||||
}
|
||||
|
||||
private boolean isInnerClass(Class<?> clazz) {
|
||||
return clazz.isMemberClass() && !isStatic(clazz);
|
||||
}
|
||||
|
||||
private boolean isStatic(Class<?> clazz) {
|
||||
return (clazz.getModifiers() & Modifier.STATIC) != 0;
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 data object that stores attributes of a field.
|
||||
*
|
||||
* <p>This class is immutable; therefore, it can be safely shared across threads.
|
||||
*
|
||||
* @author Inderjeet Singh
|
||||
* @author Joel Leitch
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
final class SyntheticFieldExclusionStrategy implements ExclusionStrategy {
|
||||
private final boolean skipSyntheticFields;
|
||||
|
||||
SyntheticFieldExclusionStrategy(boolean skipSyntheticFields) {
|
||||
this.skipSyntheticFields = skipSyntheticFields;
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return skipSyntheticFields && f.isSynthetic();
|
||||
}
|
||||
}
|
@ -23,20 +23,13 @@ import junit.framework.TestCase;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link ExposeAnnotationSerializationExclusionStrategy} class.
|
||||
* Unit tests for GsonBuilder.REQUIRE_EXPOSE_DESERIALIZE.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public class ExposeAnnotationExclusionStrategyTest extends TestCase {
|
||||
private ExposeAnnotationDeserializationExclusionStrategy deserializationStrategy;
|
||||
private ExposeAnnotationSerializationExclusionStrategy serializationStrategy;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
deserializationStrategy = new ExposeAnnotationDeserializationExclusionStrategy();
|
||||
serializationStrategy = new ExposeAnnotationSerializationExclusionStrategy();
|
||||
}
|
||||
private ExclusionStrategy deserializationStrategy = GsonBuilder.REQUIRE_EXPOSE_DESERIALIZE;
|
||||
private ExclusionStrategy serializationStrategy = GsonBuilder.REQUIRE_EXPOSE_SERIALIZE;
|
||||
|
||||
public void testNeverSkipClasses() throws Exception {
|
||||
assertFalse(deserializationStrategy.shouldSkipClass(MockObject.class));
|
||||
|
@ -35,7 +35,7 @@ public class FunctionWithInternalDependenciesTest extends TestCase {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testAnonymousLocalClassesSerialization() throws Exception {
|
||||
LinkedList<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||
strategies.add(new SyntheticFieldExclusionStrategy(true));
|
||||
strategies.add(GsonBuilder.EXCLUDE_SYNTHETIC_FIELDS);
|
||||
strategies.add(new ModifierBasedExclusionStrategy(Modifier.TRANSIENT, Modifier.STATIC));
|
||||
ExclusionStrategy exclusionStrategy = new DisjunctionExclusionStrategy(strategies);
|
||||
Gson gson = new Gson(exclusionStrategy, exclusionStrategy, FieldNamingPolicy.IDENTITY,
|
||||
|
@ -21,7 +21,7 @@ import junit.framework.TestCase;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Unit test for the {@link InnerClassExclusionStrategy} class.
|
||||
* Unit test for GsonBuilder.EXCLUDE_INNER_CLASSES.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
@ -29,14 +29,14 @@ public class InnerClassExclusionStrategyTest extends TestCase {
|
||||
public InnerClass innerClass;
|
||||
public StaticNestedClass staticNestedClass;
|
||||
|
||||
private InnerClassExclusionStrategy strategy;
|
||||
private ExclusionStrategy strategy;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
innerClass = new InnerClass();
|
||||
staticNestedClass = new StaticNestedClass();
|
||||
strategy = new InnerClassExclusionStrategy();
|
||||
strategy = GsonBuilder.EXCLUDE_INNER_CLASSES;
|
||||
}
|
||||
|
||||
public void testExcludeInnerClassObject() throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user