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) {
|
||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||
strategies.add(new InnerClassExclusionStrategy());
|
||||
strategies.add(new AnonymousAndLocalClassExclusionStrategy());
|
||||
strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY);
|
||||
if (version != VersionConstants.IGNORE_VERSIONS) {
|
||||
strategies.add(new VersionExclusionStrategy(version));
|
||||
|
@ -53,6 +53,8 @@ public final class GsonBuilder {
|
||||
|
||||
private double ignoreVersionsAfter;
|
||||
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
|
||||
private boolean serializeInnerClasses;
|
||||
private final AnonymousAndLocalClassExclusionStrategy anonAndLocalClassExclusionStrategy;
|
||||
private final InnerClassExclusionStrategy innerClassExclusionStrategy;
|
||||
private boolean excludeFieldsWithoutExposeAnnotation;
|
||||
private JsonFormatter formatter;
|
||||
@ -75,6 +77,8 @@ public final class GsonBuilder {
|
||||
public GsonBuilder() {
|
||||
// setup default values
|
||||
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
|
||||
serializeInnerClasses = true;
|
||||
anonAndLocalClassExclusionStrategy = new AnonymousAndLocalClassExclusionStrategy();
|
||||
innerClassExclusionStrategy = new InnerClassExclusionStrategy();
|
||||
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
|
||||
excludeFieldsWithoutExposeAnnotation = false;
|
||||
@ -140,6 +144,21 @@ public final class GsonBuilder {
|
||||
this.serializeNulls = true;
|
||||
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
|
||||
* and deserialization.
|
||||
@ -357,8 +376,12 @@ public final class GsonBuilder {
|
||||
*/
|
||||
public Gson create() {
|
||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
||||
strategies.add(innerClassExclusionStrategy);
|
||||
strategies.add(modifierBasedExclusionStrategy);
|
||||
strategies.add(anonAndLocalClassExclusionStrategy);
|
||||
|
||||
if (!serializeInnerClasses) {
|
||||
strategies.add(innerClassExclusionStrategy);
|
||||
}
|
||||
if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
|
||||
strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
||||
}
|
||||
|
@ -17,23 +17,28 @@
|
||||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* Strategy for excluding inner classes.
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class InnerClassExclusionStrategy implements ExclusionStrategy {
|
||||
public class InnerClassExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
public boolean shouldSkipField(Field f) {
|
||||
return isAnonymousOrLocal(f.getType());
|
||||
return isInnerClass(f.getType());
|
||||
}
|
||||
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return isAnonymousOrLocal(clazz);
|
||||
return isInnerClass(clazz);
|
||||
}
|
||||
|
||||
private boolean isAnonymousOrLocal(Class<?> clazz) {
|
||||
return clazz.isAnonymousClass() || clazz.isLocalClass();
|
||||
private boolean isInnerClass(Class<?> clazz) {
|
||||
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) {
|
||||
ObjectNavigator on = factory.create(src, typeOfSrc);
|
||||
JsonSerializationVisitor visitor =
|
||||
new JsonSerializationVisitor(factory, serializeNulls, serializers, this);
|
||||
new JsonSerializationVisitor(factory, serializeNulls, serializers, this);
|
||||
on.accept(visitor);
|
||||
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