DATAGRAPH-488 - Add Enum <-> Number converter
This commit is contained in:
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user