diff --git a/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java b/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java index 0780ba46..bb798dc4 100644 --- a/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java +++ b/src/main/java/org/springframework/data/gemfire/mapping/MappingPdxSerializer.java @@ -15,6 +15,7 @@ */ package org.springframework.data.gemfire.mapping; +import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeAllTypesFilter.EXCLUDE_ALL_TYPES; import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeComGemstoneGemFireTypesFilter.EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES; import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeJavaTypesFilter.EXCLUDE_JAVA_TYPES; import static org.springframework.data.gemfire.mapping.MappingPdxSerializer.ExcludeNullTypesFilter.EXCLUDE_NULL_TYPES; @@ -186,17 +187,19 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw private EntityInstantiators entityInstantiators; + private Filter> excludeTypeFilters = EXCLUDE_NULL_TYPES + .and(EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES) + .and(EXCLUDE_JAVA_TYPES) + .and(EXCLUDE_ORG_SPRING_FRAMEWORK_TYPES); + + private Filter> includeTypeFilters = EXCLUDE_ALL_TYPES; + private final GemfireMappingContext mappingContext; private final Logger logger = LoggerFactory.getLogger(getClass()); private Map customPdxSerializers; - private Filter typeFilters = EXCLUDE_NULL_TYPES - .and(EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES) - .and(EXCLUDE_JAVA_TYPES) - .and(EXCLUDE_ORG_SPRING_FRAMEWORK_TYPES); - // TODO: remove? SpELContext is not used private SpELContext spelContext; @@ -440,19 +443,40 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw } /** - * Sets the {@link Filter type filters} used to filter {@link Class types} serializable + * Sets the {@link Filter type filters} used to exclude or filter {@link Class types} serializable * by this {@link MappingPdxSerializer PDX serializer}. * * This operation is null-safe and rather than overriding the existing {@link Filter type filters}, * this set operation combines the given {@link Filter type filters} with * the exiting {@link Filter type filters} joined by {@literal and}. * - * @param typeFilters {@link Filter type filters} used to to filter {@link Class type} serializable + * @param typeFilters {@link Filter type filters} used to to exclude {@link Class types} serializable * by this {@link MappingPdxSerializer PDX serializer}. * @see org.springframework.data.gemfire.util.Filter */ - public void setTypeFilters(Filter> typeFilters) { - this.typeFilters = typeFilters != null ? this.typeFilters.and(typeFilters) : this.typeFilters; + public void setExcludeTypeFilters(Filter> typeFilters) { + + this.excludeTypeFilters = typeFilters != null + ? this.excludeTypeFilters.and(typeFilters) + : this.excludeTypeFilters; + } + /** + * Sets the {@link Filter type filters} used to include or filter {@link Class types} serializable + * by this {@link MappingPdxSerializer PDX serializer}. + * + * This operation is null-safe and rather than overriding the existing {@link Filter type filters}, + * this set operation combines the given {@link Filter type filters} with + * the exiting {@link Filter type filters} joined by {@literal or}. + * + * @param typeFilters {@link Filter type filters} used to to include {@link Class types} serializable + * by this {@link MappingPdxSerializer PDX serializer}. + * @see org.springframework.data.gemfire.util.Filter + */ + public void setIncludeTypeFilters(Filter> typeFilters) { + + this.includeTypeFilters = typeFilters != null + ? this.includeTypeFilters.or(typeFilters) + : this.includeTypeFilters; } /** @@ -463,7 +487,7 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw * @see org.springframework.data.gemfire.util.Filter */ protected Filter> getTypeFilters() { - return this.typeFilters; + return this.excludeTypeFilters.or(EXCLUDE_NULL_TYPES.and(this.includeTypeFilters)); } @Override @@ -657,6 +681,16 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw return obj != null ? obj.getClass() : null; } + public static class ExcludeAllTypesFilter extends org.springframework.data.gemfire.util.AbstractFilter> { + + public static final Filter> EXCLUDE_ALL_TYPES = new ExcludeAllTypesFilter(); + + @Override + public boolean accept(Class obj) { + return false; + } + } + public static class ExcludeComGemstoneGemFireTypesFilter extends org.springframework.data.gemfire.util.AbstractFilter> { public static final Filter> EXCLUDE_COM_GEMSTONE_GEMFIRE_TYPES = diff --git a/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerIntegrationTests.java index 6b580c08..3dd2ecf4 100644 --- a/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerIntegrationTests.java @@ -51,6 +51,7 @@ import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.data.annotation.Transient; import org.springframework.data.gemfire.repository.sample.Address; import org.springframework.data.gemfire.repository.sample.Person; +import org.springframework.data.gemfire.util.AbstractFilter; import lombok.AllArgsConstructor; import lombok.Data; @@ -78,6 +79,14 @@ public class MappingPdxSerializerIntegrationTests { MappingPdxSerializer serializer = MappingPdxSerializer.newMappingPdxSerializer(); + serializer.setIncludeTypeFilters(new AbstractFilter>() { + + @Override + public boolean accept(Class type) { + return type.getPackage().getName().startsWith("org.springframework.data.gemfire"); + } + }); + cache = new CacheFactory() .set("name", MappingPdxSerializerIntegrationTests.class.getSimpleName()) .set("log-level", "error") diff --git a/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java b/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java index 3faf3823..4f23affa 100644 --- a/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/mapping/MappingPdxSerializerUnitTests.java @@ -112,6 +112,19 @@ public class MappingPdxSerializerUnitTests { this.pdxSerializer = spy(new MappingPdxSerializer(this.mappingContext, this.conversionService)); } + private Filter> includePackageTypesFilter(Class type) { + + final Package includeTypesInPackage = type.getPackage(); + + return new AbstractFilter>() { + + @Override + public boolean accept(Class type) { + return includeTypesInPackage.equals(type.getPackage()); + } + }; + } + private String toFullyQualifiedPropertyName(PersistentProperty persistentProperty) { return this.pdxSerializer.toFullyQualifiedPropertyName(persistentProperty); } @@ -557,6 +570,7 @@ public class MappingPdxSerializerUnitTests { this.pdxSerializer.setCustomPdxSerializers(Collections.singletonMap(Address.class, mockAddressSerializer)); this.pdxSerializer.setGemfireInstantiators( Collections., EntityInstantiator>singletonMap(Person.class, this.mockInstantiator)); + this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class)); Object obj = this.pdxSerializer.fromData(Person.class, this.mockReader); @@ -590,6 +604,7 @@ public class MappingPdxSerializerUnitTests { try { this.pdxSerializer.setGemfireInstantiators( Collections., EntityInstantiator>singletonMap(Person.class, this.mockInstantiator)); + this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class)); this.pdxSerializer.fromData(Person.class, this.mockReader); } catch (MappingException expected) { @@ -631,6 +646,7 @@ public class MappingPdxSerializerUnitTests { this.pdxSerializer.setCustomPdxSerializers(Collections.singletonMap(Address.class, mockAddressSerializer)); this.pdxSerializer.setGemfireInstantiators( Collections., EntityInstantiator>singletonMap(Person.class, this.mockInstantiator)); + this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class)); this.pdxSerializer.fromData(Person.class, this.mockReader); GemfirePersistentEntity persistentEntity = this.mappingContext.getPersistentEntity(Person.class); @@ -645,15 +661,7 @@ public class MappingPdxSerializerUnitTests { @Test public void fromDataWithTypeFilterAcceptsApplicationDomainTypes() { - Filter> packageBasedTypeFilter = new AbstractFilter>() { - - @Override - public boolean accept(Class type) { - return type != null && User.class.getPackage().equals(type.getPackage()); - } - }; - - this.pdxSerializer.setTypeFilters(packageBasedTypeFilter); + this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(User.class)); doReturn("test").when(this.pdxSerializer).doFromData(any(Class.class), any(PdxReader.class)); @@ -684,7 +692,7 @@ public class MappingPdxSerializerUnitTests { } }; - this.pdxSerializer.setTypeFilters(applicationDomainTypeFilter); + this.pdxSerializer.setExcludeTypeFilters(applicationDomainTypeFilter); assertThat(this.pdxSerializer.fromData(ApplicationDomainType.class, this.mockReader)).isNull(); } @@ -715,6 +723,7 @@ public class MappingPdxSerializerUnitTests { jonDoe.address = address; this.pdxSerializer.setCustomPdxSerializers(Collections.singletonMap(Address.class, mockAddressSerializer)); + this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class)); assertThat(this.pdxSerializer.toData(jonDoe, this.mockWriter)).isTrue(); @@ -750,6 +759,7 @@ public class MappingPdxSerializerUnitTests { try { this.pdxSerializer.setCustomPdxSerializers(Collections.emptyMap()); + this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(Person.class)); this.pdxSerializer.toData(jonDoe, this.mockWriter); } catch (MappingException expected) { @@ -803,7 +813,7 @@ public class MappingPdxSerializerUnitTests { } }; - this.pdxSerializer.setTypeFilters(applicationDomainTypeFilter); + this.pdxSerializer.setExcludeTypeFilters(applicationDomainTypeFilter); assertThat(this.pdxSerializer.toData(new ApplicationDomainType(), this.mockWriter)).isFalse(); } @@ -815,15 +825,7 @@ public class MappingPdxSerializerUnitTests { new org.springframework.data.gemfire.test.model.Person("Jon", "Doe", null, Gender.MALE); - Filter> packageBasedTypeFilter = new AbstractFilter>() { - - @Override - public boolean accept(Class type) { - return type != null && User.class.getPackage().equals(type.getPackage()); - } - }; - - this.pdxSerializer.setTypeFilters(packageBasedTypeFilter); + this.pdxSerializer.setIncludeTypeFilters(includePackageTypesFilter(User.class)); doReturn(true).when(this.pdxSerializer).doToData(any(), any(PdxWriter.class));