From 46c85bf86d2826c5ed967d2b02ea79d82ba4241d Mon Sep 17 00:00:00 2001 From: David Montag Date: Fri, 10 Sep 2010 07:19:25 +0200 Subject: [PATCH] Added support for enum properties. --- .../graph/neo4j/spi/node/Neo4jNodeBacking.aj | 43 +++++++++++++++---- .../datastore/graph/neo4j/Person.java | 10 +++++ .../datastore/graph/neo4j/Personality.java | 5 +++ .../neo4j/spi/Neo4jGraphPersistenceTest.java | 33 +++++++++++--- 4 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 src/test/java/org/springframework/datastore/graph/neo4j/Personality.java diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/spi/node/Neo4jNodeBacking.aj b/src/main/java/org/springframework/datastore/graph/neo4j/spi/node/Neo4jNodeBacking.aj index bc605358e..ed1928678 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/spi/node/Neo4jNodeBacking.aj +++ b/src/main/java/org/springframework/datastore/graph/neo4j/spi/node/Neo4jNodeBacking.aj @@ -28,6 +28,8 @@ import org.springframework.persistence.support.AbstractTypeAnnotatingMixinFields import org.springframework.persistence.support.EntityInstantiator; import org.springframework.util.ObjectUtils; +import org.springframework.core.convert.ConversionService; + import javax.transaction.Status; import javax.transaction.SystemException; @@ -53,10 +55,14 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields relationshipEntityInstantiator; + private IndexService indexService; + +// private ConversionService conversionService; @Autowired - public void init(GraphDatabaseService gds, EntityInstantiator graphEntityInstantiator, EntityInstantiator relationshipEntityInstantiator, IndexService indexService) { + public void init(GraphDatabaseService gds, EntityInstantiator graphEntityInstantiator, + EntityInstantiator relationshipEntityInstantiator, IndexService indexService) { this.graphDatabaseService = gds; this.graphEntityInstantiator = graphEntityInstantiator; this.relationshipEntityInstantiator = relationshipEntityInstantiator; @@ -229,11 +235,11 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields Neo4J simple node property [" + propName + "] with value=[" + newVal + "]"); @@ -316,7 +322,7 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields Neo4J relationship with value=[" + newVal + "]"); @@ -377,16 +383,37 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields fieldType) { + private boolean isNeo4jPropertyType(Class fieldType) { // todo: add array support return fieldType.isPrimitive() - || (fieldType.isArray() && !fieldType.getComponentType().isArray() && isPropertyType(fieldType.getComponentType())) + || (fieldType.isArray() && !fieldType.getComponentType().isArray() && isNeo4jPropertyType(fieldType.getComponentType())) || fieldType.equals(String.class) || fieldType.equals(Character.class) || fieldType.equals(Boolean.class) || (fieldType.getName().startsWith("java.lang") && Number.class.isAssignableFrom(fieldType)); } + private boolean isConvertableType(Class fieldType) { + //return conversionService.canConvert(fieldType, String.class); + return fieldType.isEnum(); + } + + private Object serializePropertyValue(Object newVal, Class fieldType) { + if (isNeo4jPropertyType(fieldType)) { + return newVal; + } +// return conversionService.convert(newVal, String.class); + return ((Enum)newVal).name(); + } + + private Object deserializePropertyValue(Object value, Class fieldType) { + if (isNeo4jPropertyType(fieldType)) { + return value; + } +// return conversionService.convert(value, fieldType); + return Enum.valueOf((Class)fieldType, (String)value); + } + // todo @property annotation // todo fieldlist in @graphentity private boolean isIndexedProperty(Field field) { diff --git a/src/test/java/org/springframework/datastore/graph/neo4j/Person.java b/src/test/java/org/springframework/datastore/graph/neo4j/Person.java index 333b4a5d2..a107bcfb3 100644 --- a/src/test/java/org/springframework/datastore/graph/neo4j/Person.java +++ b/src/test/java/org/springframework/datastore/graph/neo4j/Person.java @@ -16,6 +16,8 @@ public class Person { private int age; private Short height; + + private Personality personality; private Person spouse; @@ -105,4 +107,12 @@ public class Person { public Friendship knows(Person p) { return (Friendship)relateTo(p, Friendship.class,"knows"); } + + public void setPersonality(Personality personality) { + this.personality = personality; + } + + public Personality getPersonality() { + return personality; + } } diff --git a/src/test/java/org/springframework/datastore/graph/neo4j/Personality.java b/src/test/java/org/springframework/datastore/graph/neo4j/Personality.java new file mode 100644 index 000000000..56aabee1a --- /dev/null +++ b/src/test/java/org/springframework/datastore/graph/neo4j/Personality.java @@ -0,0 +1,5 @@ +package org.springframework.datastore.graph.neo4j; + +public enum Personality { + EXTROVERT, INTROVERT +} diff --git a/src/test/java/org/springframework/datastore/graph/neo4j/spi/Neo4jGraphPersistenceTest.java b/src/test/java/org/springframework/datastore/graph/neo4j/spi/Neo4jGraphPersistenceTest.java index 2c1847f18..a8e612f04 100644 --- a/src/test/java/org/springframework/datastore/graph/neo4j/spi/Neo4jGraphPersistenceTest.java +++ b/src/test/java/org/springframework/datastore/graph/neo4j/spi/Neo4jGraphPersistenceTest.java @@ -18,13 +18,14 @@ import org.springframework.datastore.graph.api.NodeBacked; import org.springframework.datastore.graph.neo4j.Friendship; import org.springframework.datastore.graph.neo4j.Group; import org.springframework.datastore.graph.neo4j.Person; +import org.springframework.datastore.graph.neo4j.Personality; import org.springframework.datastore.graph.neo4j.finder.Finder; import org.springframework.datastore.graph.neo4j.finder.FinderFactory; import org.springframework.datastore.graph.neo4j.spi.node.Neo4jHelper; -import org.springframework.persistence.support.EntityInstantiator; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; +import org.springframework.persistence.support.EntityInstantiator; import java.util.*; @@ -175,7 +176,6 @@ public class Neo4jGraphPersistenceTest { Assert.assertEquals(20,p.getAge()); } - // @Test(expected = InvalidDataAccessResourceUsageException.class) @Test public void testCreateRelationshipOutsideTransaction() { Transaction tx = graphDatabaseService.beginTx(); @@ -359,6 +359,7 @@ public class Neo4jGraphPersistenceTest { Assert.assertEquals(p, f.getPerson1()); Assert.assertEquals(p2, f.getPerson2()); } + @Test @Transactional public void testGetRelationshipToReturnsRelationship() { @@ -403,6 +404,7 @@ public class Neo4jGraphPersistenceTest { Group group = new Group(); group.setReadOnlyPersons(new HashSet()); } + @Test @Transactional public void testFindGroupByIndex() { @@ -425,6 +427,7 @@ public class Neo4jGraphPersistenceTest { final Collection result = IteratorUtil.addToCollection(found.iterator(), new HashSet()); Assert.assertEquals(new HashSet(Arrays.asList(group,group2)), result); } + @Test @Transactional public void testFindAllPersonByIndexOnAnnotatedField() { @@ -433,35 +436,53 @@ public class Neo4jGraphPersistenceTest { final Person found = finder.findByPropertyValue("Person.name", "Michael"); Assert.assertEquals(person, found); } + @Test @Transactional public void testTraverseFromGroupToPeople() { - Person p=new Person("Michael",35); + Person p = new Person("Michael", 35); Group group = new Group(); group.setName("dev"); group.addPerson(p); final TraversalDescription traversalDescription = new TraversalDescriptionImpl().relationships(DynamicRelationshipType.withName("persons")).filter(Traversal.returnAllButStartNode()); - Iterable people=(Iterable)group.find(Person.class, traversalDescription); + Iterable people = (Iterable) group.find(Person.class, traversalDescription); final HashSet found = new HashSet(); for (Person person : people) { found.add(person); } Assert.assertEquals(Collections.singleton(p),found); } + @Test @Transactional public void testTraverseFromGroupToPeopleWithFinder() { final Finder finder = finderFactory.getFinderForClass(Person.class); - Person p=new Person("Michael",35); + Person p = new Person("Michael", 35); Group group = new Group(); group.setName("dev"); group.addPerson(p); final TraversalDescription traversalDescription = new TraversalDescriptionImpl().relationships(DynamicRelationshipType.withName("persons")).filter(Traversal.returnAllButStartNode()); - Iterable people=finder.findAllByTraversal(group, traversalDescription); + Iterable people = finder.findAllByTraversal(group, traversalDescription); final HashSet found = new HashSet(); for (Person person : people) { found.add(person); } Assert.assertEquals(Collections.singleton(p),found); } + + @Test + @Transactional + public void testSetPropertyConversionOfEnumProperty() { + Person p = new Person("Michael", 35); + p.setPersonality(Personality.EXTROVERT); + Assert.assertEquals("Wrong enum serialization.", "EXTROVERT", p.getUnderlyingNode().getProperty("Person.personality")); + } + + @Test + @Transactional + public void testGetPropertyConversionOfEnumProperty() { + Person p = new Person("Michael", 35); + p.getUnderlyingNode().setProperty("Person.personality", "EXTROVERT"); + Assert.assertEquals("Did not deserialize property value properly.", Personality.EXTROVERT, p.getPersonality()); + } }