Completed custom serializers in PdxMappingSerializer, SGF-125, SGF-90, SGF-127
This commit is contained in:
@@ -193,7 +193,9 @@
|
||||
com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer</classname>,
|
||||
however it is common for developers to provide their own implementation.
|
||||
The value of the attribute is simply a reference to a Spring bean that
|
||||
implements the required interface. More information on serialization support can be found in <xref linkend="serialization"/> </para>
|
||||
implements the required interface. More information on serialization
|
||||
support can be found in <xref linkend="serialization"/></para>
|
||||
|
||||
<para/>
|
||||
</section>
|
||||
</section>
|
||||
@@ -264,7 +266,7 @@
|
||||
instantiators defined declaratively to be fully initialized and
|
||||
registered before the server starts accepting connections. Keep this in
|
||||
mind when programmatically configuring these items as the server might
|
||||
start before your components and thus not be seen by the clients
|
||||
start after your components and thus not be seen by the clients
|
||||
connecting right away.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
<para>Spring Data GemFire provides support to use the Spring Data
|
||||
repository abstraction to easily persist entities into GemFire and execute
|
||||
queries. A general introduction into the repository programming model is
|
||||
been provided <ulink url="http://static.springsource.org/spring-data/data-commons/docs/current/reference/html/#repositories">here
|
||||
been provided <ulink
|
||||
url="http://static.springsource.org/spring-data/data-commons/docs/current/reference/html/#repositories">here
|
||||
</ulink>.</para>
|
||||
</section>
|
||||
|
||||
@@ -30,14 +31,14 @@
|
||||
<title>Bootstrap GemFire repositories</title>
|
||||
|
||||
<programlisting language="xml"><beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gf="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/gemfire
|
||||
http://www.springframework.org/schema/gemfire/spring-gemfire.xsd>
|
||||
http://www.springframework.org/schema/data/gemfire
|
||||
http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd>
|
||||
|
||||
<gf:repositories base-package="com.acme.repository" />
|
||||
<gfe-data:repositories base-package="com.acme.repository" />
|
||||
|
||||
</beans></programlisting>
|
||||
</example>
|
||||
@@ -88,11 +89,11 @@ public class Person { … }</programlisting>
|
||||
<title>Supported keywords for query methods</title>
|
||||
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="1*" />
|
||||
<colspec colwidth="1*"/>
|
||||
|
||||
<colspec colwidth="2*" />
|
||||
<colspec colwidth="2*"/>
|
||||
|
||||
<colspec colwidth="2*" />
|
||||
<colspec colwidth="2*"/>
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
|
||||
@@ -121,8 +121,6 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
*/
|
||||
@Override
|
||||
public Object fromData(Class<?> type, final PdxReader reader) {
|
||||
// TODO: check for custom serializer (PDX)
|
||||
|
||||
final GemfirePersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
|
||||
GemfirePropertyValueProvider propertyValueProvider = new GemfirePropertyValueProvider(reader);
|
||||
@@ -143,9 +141,15 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
if (entity.isConstructorArgument(persistentProperty)) {
|
||||
return;
|
||||
}
|
||||
// TODO: check for custom serializer (Spring Converter - primitives)
|
||||
Object value = reader.readField(persistentProperty.getName());
|
||||
|
||||
|
||||
PdxSerializer customSerializer = getCustomSerializer(persistentProperty.getType());
|
||||
Object value = null;
|
||||
if (customSerializer != null) {
|
||||
System.out.println("using custom serializer");
|
||||
value = customSerializer.fromData(persistentProperty.getType(), reader);
|
||||
} else {
|
||||
value = reader.readField(persistentProperty.getName());
|
||||
}
|
||||
try {
|
||||
wrapper.setProperty(persistentProperty, value);
|
||||
}
|
||||
@@ -166,7 +170,6 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
*/
|
||||
@Override
|
||||
public boolean toData(Object value, final PdxWriter writer) {
|
||||
// TODO: check for custom serializer (PDX)
|
||||
GemfirePersistentEntity<?> entity = mappingContext.getPersistentEntity(value.getClass());
|
||||
final BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(value, conversionService);
|
||||
|
||||
@@ -174,10 +177,15 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) {
|
||||
// TODO: check for custom serializer (Spring Converter)
|
||||
|
||||
try {
|
||||
Object propertyValue = wrapper.getProperty(persistentProperty);
|
||||
writer.writeField(persistentProperty.getName(), propertyValue, (Class) persistentProperty.getType());
|
||||
PdxSerializer customSerializer = getCustomSerializer(persistentProperty.getType());
|
||||
if (customSerializer != null) {
|
||||
customSerializer.toData(propertyValue, writer);
|
||||
} else {
|
||||
writer.writeField(persistentProperty.getName(), propertyValue, (Class) persistentProperty.getType());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException("Could not write value for property " + persistentProperty.toString(), e);
|
||||
@@ -193,4 +201,8 @@ public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAw
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private PdxSerializer getCustomSerializer(Class<?> clazz) {
|
||||
return customSerializers == null ? null : customSerializers.get(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,12 +122,12 @@ when the same cache is used in multiple application context/bean factories insid
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="pdx-serializer" type="xsd:string"
|
||||
<xsd:attribute name="pdx-serializer-ref" type="xsd:string"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Sets the PDX serializer for the cache. If this serializer is set, it will be consulted to see if it can serialize any
|
||||
domain classes which are added to the cache in portable data exchange format.
|
||||
domain classes which are added to the cache in portable data exchange (PDX) format.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -18,16 +18,21 @@ package org.springframework.data.gemfire.mapping;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.gemfire.repository.sample.Address;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
|
||||
import com.gemstone.gemfire.DataSerializable;
|
||||
import com.gemstone.gemfire.Instantiator;
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.CacheFactory;
|
||||
import com.gemstone.gemfire.cache.DataPolicy;
|
||||
@@ -41,12 +46,12 @@ import com.gemstone.gemfire.cache.RegionFactory;
|
||||
*/
|
||||
public class MappingPdxSerializerIntegrationTest {
|
||||
|
||||
Region<Object, Object> region;
|
||||
static Region<Object, Object> region;
|
||||
|
||||
static Cache cache;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
|
||||
MappingPdxSerializer serializer = new MappingPdxSerializer(new GemfireMappingContext(),
|
||||
new DefaultConversionService());
|
||||
@@ -81,6 +86,29 @@ public class MappingPdxSerializerIntegrationTest {
|
||||
assertThat(reference.getLastname(), is(person.getLastname()));
|
||||
assertThat(reference.address, is(person.address));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeAndDeserializeCorrectlyWithDataSerializable() {
|
||||
|
||||
Address address = new Address();
|
||||
address.zipCode = "01234";
|
||||
address.city = "London";
|
||||
|
||||
PersonWithDataSerializableProperty person = new PersonWithDataSerializableProperty(2L, "Oliver", "Gierke", new DataSerializableProperty("foo"));
|
||||
person.address = address;
|
||||
|
||||
region.put(2L, person);
|
||||
Object result = region.get(2L);
|
||||
|
||||
assertThat(result instanceof PersonWithDataSerializableProperty, is(true));
|
||||
|
||||
PersonWithDataSerializableProperty reference = person;
|
||||
assertThat(reference.getFirstname(), is(person.getFirstname()));
|
||||
assertThat(reference.getLastname(), is(person.getLastname()));
|
||||
assertThat(reference.address, is(person.address));
|
||||
assertThat(reference.dsProperty.getValue(),is("foo"));
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
@@ -99,4 +127,57 @@ public class MappingPdxSerializerIntegrationTest {
|
||||
new File(name).delete();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class PersonWithDataSerializableProperty extends Person {
|
||||
|
||||
private DataSerializableProperty dsProperty;
|
||||
|
||||
public PersonWithDataSerializableProperty(Long id, String firstname,
|
||||
String lastname, DataSerializableProperty dsProperty) {
|
||||
super(id, firstname, lastname);
|
||||
this.dsProperty = dsProperty;
|
||||
}
|
||||
|
||||
public DataSerializableProperty getDataSerializableProperty() {
|
||||
return this.dsProperty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class DataSerializableProperty implements DataSerializable {
|
||||
|
||||
static {
|
||||
Instantiator.register(new Instantiator(DataSerializableProperty.class,101) {
|
||||
public DataSerializable newInstance() {
|
||||
return new DataSerializableProperty("");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String value;
|
||||
|
||||
public DataSerializableProperty(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void fromData(DataInput dataInput) throws IOException,
|
||||
ClassNotFoundException {
|
||||
value = dataInput.readUTF();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toData(DataOutput dataOutput) throws IOException {
|
||||
dataOutput.writeUTF(value);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,12 @@ import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
import org.springframework.data.gemfire.repository.sample.Address;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
|
||||
import com.gemstone.gemfire.pdx.PdxReader;
|
||||
import com.gemstone.gemfire.pdx.PdxSerializer;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MappingPdxSerializer}.
|
||||
@@ -50,6 +52,9 @@ public class MappingPdxSerializerUnitTests {
|
||||
EntityInstantiator instantiator;
|
||||
@Mock
|
||||
PdxReader reader;
|
||||
|
||||
@Mock
|
||||
PdxSerializer addressSerializer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -57,14 +62,21 @@ public class MappingPdxSerializerUnitTests {
|
||||
context = new GemfireMappingContext();
|
||||
conversionService = new GenericConversionService();
|
||||
serializer = new MappingPdxSerializer(context, conversionService);
|
||||
Map<Class<?>,PdxSerializer> customSerializers = new HashMap<Class<?>, PdxSerializer>();
|
||||
customSerializers.put(Address.class, addressSerializer);
|
||||
serializer.setCustomSerializers(customSerializers);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void usesRegisteredInstantiator() {
|
||||
Address address = new Address();
|
||||
address.zipCode = "01234";
|
||||
address.city = "London";
|
||||
|
||||
Person person = new Person(1L, "Oliver", "Gierke");
|
||||
|
||||
person.address = address;
|
||||
|
||||
ParameterValueProvider<GemfirePersistentProperty> provider = any(ParameterValueProvider.class);
|
||||
GemfirePersistentEntity<?> entity = any(GemfirePersistentEntity.class);
|
||||
when(instantiator.createInstance(entity, provider)).thenReturn(person);
|
||||
@@ -77,5 +89,6 @@ public class MappingPdxSerializerUnitTests {
|
||||
|
||||
verify(instantiator, times(1)).createInstance(eq(context.getPersistentEntity(Person.class)),
|
||||
any(ParameterValueProvider.class));
|
||||
verify(addressSerializer,times(1)).fromData(eq(Address.class), any(PdxReader.class));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user