Add the ability to configure Gson to exclude serializing and deserializing of all "Inner Classes".
This commit is contained in:
parent
73117fe652
commit
54a480774d
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy for excluding anonymous and local classes.
|
||||||
|
*
|
||||||
|
* @author Joel Leitch
|
||||||
|
*/
|
||||||
|
final class AnonymousAndLocalClassExclusionStrategy implements ExclusionStrategy {
|
||||||
|
|
||||||
|
public boolean shouldSkipField(Field f) {
|
||||||
|
return isAnonymousOrLocal(f.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldSkipClass(Class<?> clazz) {
|
||||||
|
return isAnonymousOrLocal(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAnonymousOrLocal(Class<?> clazz) {
|
||||||
|
return clazz.isAnonymousClass() || clazz.isLocalClass();
|
||||||
|
}
|
||||||
|
}
|
@ -182,7 +182,7 @@ public final class Gson {
|
|||||||
|
|
||||||
private static ExclusionStrategy createExclusionStrategy(double version) {
|
private static ExclusionStrategy createExclusionStrategy(double version) {
|
||||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||||
strategies.add(new InnerClassExclusionStrategy());
|
strategies.add(new AnonymousAndLocalClassExclusionStrategy());
|
||||||
strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY);
|
strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY);
|
||||||
if (version != VersionConstants.IGNORE_VERSIONS) {
|
if (version != VersionConstants.IGNORE_VERSIONS) {
|
||||||
strategies.add(new VersionExclusionStrategy(version));
|
strategies.add(new VersionExclusionStrategy(version));
|
||||||
|
@ -53,6 +53,8 @@ public final class GsonBuilder {
|
|||||||
|
|
||||||
private double ignoreVersionsAfter;
|
private double ignoreVersionsAfter;
|
||||||
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
|
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
|
||||||
|
private boolean serializeInnerClasses;
|
||||||
|
private final AnonymousAndLocalClassExclusionStrategy anonAndLocalClassExclusionStrategy;
|
||||||
private final InnerClassExclusionStrategy innerClassExclusionStrategy;
|
private final InnerClassExclusionStrategy innerClassExclusionStrategy;
|
||||||
private boolean excludeFieldsWithoutExposeAnnotation;
|
private boolean excludeFieldsWithoutExposeAnnotation;
|
||||||
private JsonFormatter formatter;
|
private JsonFormatter formatter;
|
||||||
@ -75,6 +77,8 @@ public final class GsonBuilder {
|
|||||||
public GsonBuilder() {
|
public GsonBuilder() {
|
||||||
// setup default values
|
// setup default values
|
||||||
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
|
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
|
||||||
|
serializeInnerClasses = true;
|
||||||
|
anonAndLocalClassExclusionStrategy = new AnonymousAndLocalClassExclusionStrategy();
|
||||||
innerClassExclusionStrategy = new InnerClassExclusionStrategy();
|
innerClassExclusionStrategy = new InnerClassExclusionStrategy();
|
||||||
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
|
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
|
||||||
excludeFieldsWithoutExposeAnnotation = false;
|
excludeFieldsWithoutExposeAnnotation = false;
|
||||||
@ -140,6 +144,21 @@ public final class GsonBuilder {
|
|||||||
this.serializeNulls = true;
|
this.serializeNulls = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to include or exclude inner classes
|
||||||
|
*
|
||||||
|
* @param modifiers the field modifiers. You must use the modifiers specified in the
|
||||||
|
* {@link java.lang.reflect.Modifier} class. For example,
|
||||||
|
* {@link java.lang.reflect.Modifier#TRANSIENT},
|
||||||
|
* {@link java.lang.reflect.Modifier#STATIC}.
|
||||||
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
public GsonBuilder serializeInnerClasses(boolean value) {
|
||||||
|
serializeInnerClasses = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures Gson to apply a specific naming policy to an object's field during serialization
|
* Configures Gson to apply a specific naming policy to an object's field during serialization
|
||||||
* and deserialization.
|
* and deserialization.
|
||||||
@ -357,8 +376,12 @@ public final class GsonBuilder {
|
|||||||
*/
|
*/
|
||||||
public Gson create() {
|
public Gson create() {
|
||||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||||
strategies.add(innerClassExclusionStrategy);
|
|
||||||
strategies.add(modifierBasedExclusionStrategy);
|
strategies.add(modifierBasedExclusionStrategy);
|
||||||
|
strategies.add(anonAndLocalClassExclusionStrategy);
|
||||||
|
|
||||||
|
if (!serializeInnerClasses) {
|
||||||
|
strategies.add(innerClassExclusionStrategy);
|
||||||
|
}
|
||||||
if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
|
if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
|
||||||
strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
||||||
}
|
}
|
||||||
|
@ -17,23 +17,28 @@
|
|||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strategy for excluding inner classes.
|
* Strategy for excluding inner classes.
|
||||||
*
|
*
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
*/
|
*/
|
||||||
final class InnerClassExclusionStrategy implements ExclusionStrategy {
|
public class InnerClassExclusionStrategy implements ExclusionStrategy {
|
||||||
|
|
||||||
public boolean shouldSkipField(Field f) {
|
public boolean shouldSkipField(Field f) {
|
||||||
return isAnonymousOrLocal(f.getType());
|
return isInnerClass(f.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldSkipClass(Class<?> clazz) {
|
public boolean shouldSkipClass(Class<?> clazz) {
|
||||||
return isAnonymousOrLocal(clazz);
|
return isInnerClass(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAnonymousOrLocal(Class<?> clazz) {
|
private boolean isInnerClass(Class<?> clazz) {
|
||||||
return clazz.isAnonymousClass() || clazz.isLocalClass();
|
return clazz.isMemberClass() && !isStatic(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStatic(Class<?> clazz) {
|
||||||
|
return (clazz.getModifiers() & Modifier.STATIC) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ final class JsonSerializationContextDefault implements JsonSerializationContext
|
|||||||
public JsonElement serialize(Object src, Type typeOfSrc) {
|
public JsonElement serialize(Object src, Type typeOfSrc) {
|
||||||
ObjectNavigator on = factory.create(src, typeOfSrc);
|
ObjectNavigator on = factory.create(src, typeOfSrc);
|
||||||
JsonSerializationVisitor visitor =
|
JsonSerializationVisitor visitor =
|
||||||
new JsonSerializationVisitor(factory, serializeNulls, serializers, this);
|
new JsonSerializationVisitor(factory, serializeNulls, serializers, this);
|
||||||
on.accept(visitor);
|
on.accept(visitor);
|
||||||
return visitor.getJsonElement();
|
return visitor.getJsonElement();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.Field;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for the {@link InnerClassExclusionStrategy} class.
|
||||||
|
*
|
||||||
|
* @author Joel Leitch
|
||||||
|
*/
|
||||||
|
public class InnerClassExclusionStrategyTest extends TestCase {
|
||||||
|
public InnerClass innerClass;
|
||||||
|
public StaticNestedClass staticNestedClass;
|
||||||
|
|
||||||
|
private InnerClassExclusionStrategy strategy;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
innerClass = new InnerClass();
|
||||||
|
staticNestedClass = new StaticNestedClass();
|
||||||
|
strategy = new InnerClassExclusionStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExcludeInnerClassObject() throws Exception {
|
||||||
|
Class<?> clazz = innerClass.getClass();
|
||||||
|
assertTrue(strategy.shouldSkipClass(clazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExcludeInnerClassField() throws Exception {
|
||||||
|
Field f = getClass().getField("innerClass");
|
||||||
|
assertTrue(strategy.shouldSkipField(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIncludeStaticNestedClassObject() throws Exception {
|
||||||
|
Class<?> clazz = staticNestedClass.getClass();
|
||||||
|
assertFalse(strategy.shouldSkipClass(clazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIncludeStaticNestedClassField() throws Exception {
|
||||||
|
Field f = getClass().getField("staticNestedClass");
|
||||||
|
assertFalse(strategy.shouldSkipField(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
class InnerClass {
|
||||||
|
}
|
||||||
|
|
||||||
|
static class StaticNestedClass {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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.functional;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs some functional testing to ensure GSON infrastructure properly serializes/deserializes
|
||||||
|
* fields that either should or should not be included in the output based on the GSON
|
||||||
|
* configuration.
|
||||||
|
*
|
||||||
|
* @author Joel Leitch
|
||||||
|
*/
|
||||||
|
public class FieldExclusionTest extends TestCase {
|
||||||
|
private static final String VALUE = "blah_1234";
|
||||||
|
|
||||||
|
public void testDefaultInnerClassExclusion() throws Exception {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
TestInnerClass target = new TestInnerClass(VALUE);
|
||||||
|
String result = gson.toJson(target);
|
||||||
|
assertEquals(target.toJson(), result);
|
||||||
|
|
||||||
|
gson = new GsonBuilder().create();
|
||||||
|
target = new TestInnerClass(VALUE);
|
||||||
|
result = gson.toJson(target);
|
||||||
|
assertEquals(target.toJson(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInnerClassExclusion() throws Exception {
|
||||||
|
Gson gson = new GsonBuilder().serializeInnerClasses(false).create();
|
||||||
|
TestInnerClass target = new TestInnerClass(VALUE);
|
||||||
|
String result = gson.toJson(target);
|
||||||
|
assertEquals("", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDefaultNestedStaticClassIncluded() throws Exception {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
TestInnerClass target = new TestInnerClass(VALUE);
|
||||||
|
String result = gson.toJson(target);
|
||||||
|
assertEquals(target.toJson(), result);
|
||||||
|
|
||||||
|
gson = new GsonBuilder().create();
|
||||||
|
target = new TestInnerClass(VALUE);
|
||||||
|
result = gson.toJson(target);
|
||||||
|
assertEquals(target.toJson(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestInnerClass extends TestStaticNestedClass {
|
||||||
|
public TestInnerClass(String value) {
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestStaticNestedClass {
|
||||||
|
private final String value;
|
||||||
|
public TestStaticNestedClass(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toJson() {
|
||||||
|
return "{\"value\":\"" + value + "\"}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user