DATAGRAPH-488 - Add Enum <-> Number converter

This commit is contained in:
Michael Hunger
2014-06-30 10:27:18 +02:00
parent d218e55c8c
commit 11bf406fc5
2 changed files with 128 additions and 0 deletions

View File

@@ -27,6 +27,7 @@ import org.springframework.data.geo.Point;
import org.springframework.data.geo.Shape;
import org.springframework.data.neo4j.repository.GeoConverter;
import java.util.Arrays;
import java.util.Date;
public class Neo4jConversionServiceFactoryBean implements FactoryBean<ConversionService> {
@@ -47,11 +48,13 @@ public class Neo4jConversionServiceFactoryBean implements FactoryBean<Conversion
registry.addConverter(new StringToDateConverter());
registry.addConverter(new NumberToDateConverter());
registry.addConverter(new EnumToStringConverter());
registry.addConverter(new EnumToIntegerConverter());
registry.addConverter(new ShapeToStringConverter());
registry.addConverter(new StringToShapeConverter());
registry.addConverter(new PointToStringConverter());
registry.addConverter(new StringToPointConverter());
registry.addConverterFactory(new StringToEnumConverterFactory());
registry.addConverterFactory(new NumberToEnumConverterFactory());
} else {
throw new IllegalArgumentException("conversionservice is no ConverterRegistry:" + service);
}
@@ -105,6 +108,13 @@ public class Neo4jConversionServiceFactoryBean implements FactoryBean<Conversion
return source.name();
}
}
public static class EnumToIntegerConverter implements Converter<Enum, Integer> {
@Override
public Integer convert(Enum source) {
return source.ordinal();
}
}
public static class ShapeToStringConverter implements Converter<Shape, String> {
@@ -163,4 +173,30 @@ public class Neo4jConversionServiceFactoryBean implements FactoryBean<Conversion
}
}
public static class NumberToEnumConverterFactory implements ConverterFactory<Number, Enum> {
@SuppressWarnings("unchecked")
public <T extends Enum> Converter<Number, T> getConverter(Class<T> targetType) {
return new NumberToEnum(targetType);
}
private static class NumberToEnum<T extends Enum> implements Converter<Number, T> {
private final Class<T> enumType;
public NumberToEnum(Class<T> enumType) {
this.enumType = enumType;
}
@SuppressWarnings("RedundantCast")
public T convert(Number source) {
if (source == null) return null;
T[] values = this.enumType.getEnumConstants();
int ordinal = source.intValue();
if (ordinal < 0 || ordinal >= values.length) throw new IllegalArgumentException("Ordinal value for Enum out of range "+ordinal+" "+ Arrays.toString(values));
return (T)values[ordinal];
}
}
}
}

View File

@@ -0,0 +1,92 @@
package org.springframework.data.neo4j.conversion;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.test.TestGraphDatabaseFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.GraphProperty;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.index.IndexType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.Assert.assertEquals;
/**
* @author mh
* @since 30.06.14
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class EnumConverterTests {
@Configuration
@EnableNeo4jRepositories
static class TestConfig extends Neo4jConfiguration {
TestConfig() {
setBasePackage("org.springframework.data.neo4j.conversion");
}
@Bean
GraphDatabaseService graphDatabaseService() {
return new TestGraphDatabaseFactory().newImpermanentDatabase();
}
}
@Autowired
Neo4jTemplate template;
static enum Letter {
A, B, C
}
static enum Vowel {
A, E, I, O, U
}
static enum Consonant {
B,C,D,F,G,H
}
@NodeEntity
static class Word {
@GraphId
Long id;
@Indexed(unique = true, indexType = IndexType.LABEL)
Letter letter;
@GraphProperty(propertyType = String.class)
Vowel vowel;
@GraphProperty(propertyType = Integer.class)
Consonant consonant;
Word() { }
Word(Letter letter, Vowel vowel, Consonant consonant) {
this.letter = letter;
this.vowel = vowel;
this.consonant = consonant;
}
}
@Test
@Transactional
public void testConvertEnumsAccordingToAnnotation() throws Exception {
Word word = template.save(new Word(Letter.C, Vowel.A, Consonant.B));
assertEquals(Letter.C, word.letter);
assertEquals(Vowel.A, word.vowel);
assertEquals(Consonant.B, word.consonant);
PropertyContainer node = template.getPersistentState(word);
assertEquals(Letter.C.name(),node.getProperty("letter"));
assertEquals(Vowel.A.name(),node.getProperty("vowel"));
assertEquals(Consonant.B.ordinal(),node.getProperty("consonant"));
}
}