david: extended tests, added relationship info

This commit is contained in:
Michael Hunger
2010-08-09 23:25:30 +02:00
parent b9f71bdebc
commit 529671b975
3 changed files with 143 additions and 34 deletions

View File

@@ -2,6 +2,7 @@ package org.springframework.persistence.graph.neo4j;
import java.lang.reflect.Field;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.FieldSignature;
import org.neo4j.graphdb.Direction;
@@ -118,7 +119,7 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
if (me == null) {
throw new IllegalStateException("Entity must have a backing Node");
}
org.neo4j.graphdb.Relationship singleRelationship = getRelationship(me, fieldSignature);
org.neo4j.graphdb.Relationship singleRelationship = getRelationship(me, new RelationshipInfo(fieldSignature));
// TODO is this correct
// [mh] i assume only for null
@@ -137,15 +138,8 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
}
private org.neo4j.graphdb.Relationship getRelationship(Node me, FieldSignature f) {
Relationship r = f.getField().getAnnotation(Relationship.class);
if (r == null) {
RelationshipType type=DynamicRelationshipType.withName(getNeo4jPropertyName((Signature)f));
return me.getSingleRelationship(type, Direction.OUTGOING);
}
RelationshipType type = DynamicRelationshipType.withName(r.type());
org.neo4j.graphdb.Relationship singleRelationship = me.getSingleRelationship(type, r.direction().toNeo4jDir());
return singleRelationship;
private org.neo4j.graphdb.Relationship getRelationship(Node me, RelationshipInfo relInfo) {
return me.getSingleRelationship(relInfo.getType(), relInfo.getDirection());
}
@@ -162,12 +156,8 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
// Look for a relationship
if (isNeo4jRelationshipField(f)) {
Relationship r = f.getAnnotation(Relationship.class);
if (r == null) {
graphEntityFieldSet(entity, (NodeBacked) newVal, getNeo4jPropertyName(thisJoinPoint.getSignature()),Direction.OUTGOING);
} else {
graphEntityFieldSet(entity, (NodeBacked) newVal, r.type(), r.direction().toNeo4jDir());
}
RelationshipInfo relInfo = new RelationshipInfo(fieldSignature);
graphEntityFieldSet(entity, (NodeBacked) newVal, relInfo.getType(), relInfo.getDirection());
log.info("SET " + f + " -> Neo4J relationship with value=[" + newVal + "]");
return null;
}
@@ -178,10 +168,16 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
}
// todo what happens to the previous value, remove relationships?
private void graphEntityFieldSet(NodeBacked entity, NodeBacked newVal, String relationshipName, Direction direction) {
RelationshipType type = DynamicRelationshipType.withName(relationshipName);
private void graphEntityFieldSet(NodeBacked entity, NodeBacked newVal, RelationshipType relationshipType, Direction direction) {
RelationshipType type = relationshipType;//DynamicRelationshipType.withName(relationshipTypeName);
Node me = entity.getUnderlyingNode();
for ( org.neo4j.graphdb.Relationship relationship : me.getRelationships(type, direction) ) {
relationship.delete();
}
if (newVal == null) {
return;
}
Node targetNode = newVal.getUnderlyingNode();
switch(direction) {
case OUTGOING : me.createRelationshipTo(targetNode, type); break;
@@ -198,9 +194,27 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
return NodeBacked.class.isAssignableFrom(f.getType());
}
private String getNeo4jPropertyName(Signature sig) {
// TODO: Do something better with this.
private static String getNeo4jPropertyName(Signature sig) {
return sig.toShortString();
}
public static class RelationshipInfo {
private Relationship relAnnotation;
private final FieldSignature fieldSignature;
public RelationshipInfo(FieldSignature fieldSignature) {
this.fieldSignature = fieldSignature;
relAnnotation = fieldSignature.getField().getAnnotation(Relationship.class);
}
public RelationshipType getType() {
return DynamicRelationshipType.withName((relAnnotation == null) ? getNeo4jPropertyName(fieldSignature) : relAnnotation.type());
}
public Direction getDirection() {
return (relAnnotation == null) ? Direction.OUTGOING : relAnnotation.direction().toNeo4jDir();
}
}
}

View File

@@ -15,8 +15,14 @@ public class Person {
Person spouse;
@Relationship(type="mother",direction=Direction.BOTH)
@Relationship(type="mother", direction=Direction.OUTGOING)
Person mother;
@Relationship(type="boss", direction=Direction.INCOMING)
Person boss;
@Relationship(type="friend", direction=Direction.BOTH)
Person friend;
public Person(String name, int age) {
this.name = name;
@@ -44,18 +50,31 @@ public class Person {
return spouse;
}
public void setSpouse(Person spouse) {
this.spouse = spouse;
}
public Person getMother() {
return mother;
}
public void setMother(Person mother) {
this.mother = mother;
}
public Person getBoss() {
return boss;
}
public void setBoss(Person boss) {
this.boss = boss;
}
public Person getFriend() {
return friend;
}
public void setFriend(Person friend) {
this.friend = friend;
}
}

View File

@@ -4,6 +4,7 @@ import junit.framework.Assert;
import org.junit.After;
import org.junit.Test;
import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.GraphDatabaseService;
@@ -18,12 +19,16 @@ import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class Neo4jGraphPersistenceTest {
protected final Log log = LogFactory.getLog(getClass());
@Autowired
private EntityInstantiator<NodeBacked,Node> nodeInstantiator;
@@ -42,8 +47,7 @@ public class Neo4jGraphPersistenceTest {
@Transactional
@Rollback(false)
public void testUserConstructor() {
int age = 39;
Person p = new Person("Rod", age);
Person p = new Person("Rod", 39);
Assert.assertEquals(p.getName(), p.getUnderlyingNode().getProperty("Person.name"));
Assert.assertEquals(p.getAge(), p.getUnderlyingNode().getProperty("Person.age"));
insertedId = p.getId();
@@ -51,19 +55,91 @@ public class Neo4jGraphPersistenceTest {
@Test
@Transactional
public void testCreateRelationshipOnSet() {
Person p = new Person("Michael", 35);
Person spouse=new Person("Tina",36);
p.setSpouse(spouse);
Assert.assertEquals("Tina", p.getSpouse().getUnderlyingNode().getProperty("Person.name"));
Node spouseNode=p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode();
Assert.assertEquals(spouse.getUnderlyingNode(), spouseNode);
public void testSetProperties() {
Person p = new Person("Foo", 2);
p.setName("Michael");
p.setAge(35);
Assert.assertEquals("Michael", p.getUnderlyingNode().getProperty("Person.name"));
Assert.assertEquals(35, p.getUnderlyingNode().getProperty("Person.age"));
}
@Test
@Transactional
public void testCreateRelationshipWithoutAnnotationOnSet() {
log.debug("testCreateRelationshipWithoutAnnotationOnSet");
Person p = new Person("Michael", 35);
Person spouse = new Person("Tina",36);
p.setSpouse(spouse);
Node spouseNode=p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode();
Assert.assertEquals(spouse.getUnderlyingNode(), spouseNode);
Assert.assertEquals(spouse, p.getSpouse());
}
@Test
@Transactional
public void testCreateRelationshipWithAnnotationOnSet() {
log.debug("testCreateRelationshipWithAnnotationOnSet");
Person p = new Person("Michael", 35);
Person mother = new Person("Gabi",60);
p.setMother(mother);
Node motherNode = p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("mother"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode();
Assert.assertEquals(mother.getUnderlyingNode(), motherNode);
Assert.assertEquals(mother, p.getMother());
}
// TODO test delete relationship
@Test
@Transactional
public void testDeleteRelationship() {
log.debug("testDeleteRelationship");
Person p = new Person("Michael", 35);
Person spouse = new Person("Tina", 36);
p.setSpouse(spouse);
p.setSpouse(null);
Assert.assertNull(p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING));
Assert.assertNull(p.getSpouse());
}
// TODO test delete previous relationship
@Test
@Transactional
public void testDeletePreviousRelationshipOnNewRelationship() {
log.debug("testDeletePreviousRelationshipOnNewRelationship");
Person p = new Person("Michael", 35);
Person spouse = new Person("Tina", 36);
Person friend = new Person("Helga", 34);
p.setSpouse(spouse);
p.setSpouse(friend);
Assert.assertEquals(friend.getUnderlyingNode(), p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode());
Assert.assertEquals(friend, p.getSpouse());
}
// TODO test incoming relationship
@Test
@Transactional
public void testCreateIncomingRelationshipWithAnnotationOnSet() {
Person p = new Person("David", 25);
Person boss = new Person("Emil", 32);
p.setBoss(boss);
Assert.assertEquals(boss.getUnderlyingNode(), p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("boss"), org.neo4j.graphdb.Direction.INCOMING).getStartNode());
Assert.assertEquals(boss, p.getBoss());
}
// TODO test bidirectional relationship
@Ignore
@Test
@Transactional
public void testBidirectionalRelationshipWithAnnotationOnSet() {
Person p = new Person("Michael", 35);
Person friend = new Person("David", 25);
p.setFriend(friend);
}
// TODO test remove property (set to null)
@Test
@Transactional
public void testInstantiatedFinder() {
log.debug("testInstantiatedFinder");
Node n = findPersonTestNode();
Person found = nodeInstantiator.createEntityFromState(n, Person.class);
Assert.assertEquals("Rod", found.getUnderlyingNode().getProperty("Person.name"));