diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractFieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractFieldAccessor.java index 0f98356b9..0431c9d0d 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractFieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractFieldAccessor.java @@ -28,19 +28,18 @@ public abstract class AbstractFieldAccessor implements FieldAccessor { this.type = type; } - protected NodeBacked createSingleRelationship(NodeBacked entity, NodeBacked target) { - if (target==null) return null; + protected void createSingleRelationship(Node start, Node end) { + if (end==null) return; switch(direction) { case OUTGOING : { - obtainSingleRelationship(entity.getUnderlyingNode(), target.getUnderlyingNode()); + obtainSingleRelationship(start, end); break; } case INCOMING : - obtainSingleRelationship(target.getUnderlyingNode(), entity.getUnderlyingNode()); + obtainSingleRelationship(end, start); break; default : throw new InvalidDataAccessApiUsageException("invalid direction " + direction); } - return target; } private Relationship obtainSingleRelationship(Node start, Node end) { @@ -49,97 +48,42 @@ public abstract class AbstractFieldAccessor implements FieldAccessor { return start.createRelationshipTo(end, type); } - protected void checkCircularReference(NodeBacked entity, NodeBacked target) { - Node entityNode = entity.getUnderlyingNode(); - Node targetNode = target.getUnderlyingNode(); - if (entityNode.equals(targetNode)) { - throw new InvalidDataAccessApiUsageException("Cannot create circular reference."); - } - } - - protected NodeBacked checkTargetTypeNodebacked(Object newVal) { - if (newVal != null && !(newVal instanceof NodeBacked)) { - throw new IllegalArgumentException("New value must be NodeBacked."); - } - final NodeBacked target = (NodeBacked) newVal; - if (target!=null) checkUnderlyingNode(target); - return target; - } - - protected void removeRelationships(NodeBacked entity) { - Node entityNode = entity.getUnderlyingNode(); - for ( Relationship relationship : entityNode.getRelationships(type, direction) ) { - relationship.delete(); - } - } - - protected Object createEntityFromRelationshipEndNode(Node entityNode) { - Relationship singleRelationship = entityNode.getSingleRelationship(type, direction); - - if (singleRelationship == null) { - return null; - } - Node targetNode = singleRelationship.getOtherNode(entityNode); - return graphEntityInstantiator.createEntityFromState(targetNode, relatedType); - } - - protected void checkUnderlyingNode(NodeBacked entity) { + protected Node checkUnderlyingNode(NodeBacked entity) { if (entity==null) throw new IllegalStateException("Entity is null"); - Node entityNode = entity.getUnderlyingNode(); - if (entityNode == null) { - throw new IllegalStateException("Entity must have a backing Node"); - } + Node node = entity.getUnderlyingNode(); + if (node != null) return node; + throw new IllegalStateException("Entity must have a backing Node"); } - protected boolean isExistingRelationship(final NodeBacked entity, final NodeBacked target) { - final Node targetNode = target.getUnderlyingNode(); - for (final Relationship relationship : getRelationships(entity)) { - if (relationship.getEndNode().equals(targetNode)) return true; - } - return false; - } - - private Iterable getRelationships(final NodeBacked entity) { - return entity.getUnderlyingNode().getRelationships(type, direction); - } - - protected void removeMissingRelationships(NodeBacked entity, Set target) { - Set newNodes = extractNodes(target); - Node entityNode = entity.getUnderlyingNode(); - for ( Relationship relationship : entityNode.getRelationships(type, direction) ) { - if (!newNodes.remove(relationship.getOtherNode(entityNode))) + protected void removeMissingRelationships(Node node, Set targetNodes) { + for ( Relationship relationship : node.getRelationships(type, direction) ) { + if (!targetNodes.remove(relationship.getOtherNode(node))) relationship.delete(); } } - private Set extractNodes(Set target) { - Set newNodes=new HashSet(); - for (NodeBacked nodeBacked : target) { - newNodes.add(nodeBacked.getUnderlyingNode()); - } - return newNodes; - } - - protected void createNewRelationshipsFrom(NodeBacked entity, Set target) { - for (NodeBacked nodeBacked : target) { - createSingleRelationship(entity,nodeBacked); + protected void createAddedRelationships(Node node, Set targetNodes) { + for (Node targetNode : targetNodes) { + createSingleRelationship(node,targetNode); } } - protected void checkNoCircularReference(NodeBacked entity, Set target) { - if (target.contains(entity)) throw new InvalidDataAccessApiUsageException("Cannot create a circular reference to "+target); + protected void checkNoCircularReference(Node node, Set targetNodes) { + if (targetNodes.contains(node)) throw new InvalidDataAccessApiUsageException("Cannot create a circular reference to "+ targetNodes); } - protected Set checkTargetIsSetOfNodebacked(Object newVal) { + protected Set checkTargetIsSetOfNodebacked(Object newVal) { if (!(newVal instanceof Set)) { throw new IllegalArgumentException("New value must be a Set, was: " + newVal.getClass()); } + Set nodes=new HashSet(); for (Object value : (Set) newVal) { if (!(value instanceof NodeBacked)) { throw new IllegalArgumentException("New value elements must be NodeBacked."); } + nodes.add(((NodeBacked)value).getUnderlyingNode()); } - return (Set) newVal; + return nodes; } protected ManagedFieldAccessorSet createManagedSet(NodeBacked entity, Set result) { diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessor.java index 73fd82ea0..652371a9c 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessor.java @@ -16,16 +16,16 @@ public class OneToNRelationshipFieldAccessor extends AbstractFieldAccessor { } public Object setValue(final NodeBacked entity, final Object newVal) { - checkUnderlyingNode(entity); + final Node node = checkUnderlyingNode(entity); if (newVal==null) { - removeMissingRelationships(entity, Collections.emptySet()); + removeMissingRelationships(node, Collections.emptySet()); return null; } - final Set target = checkTargetIsSetOfNodebacked(newVal); - checkNoCircularReference(entity,target); - removeMissingRelationships(entity, target); - createNewRelationshipsFrom(entity,target); - return createManagedSet(entity, target); + final Set targetNodes = checkTargetIsSetOfNodebacked(newVal); + checkNoCircularReference(node,targetNodes); + removeMissingRelationships(node, targetNodes); + createAddedRelationships(node,targetNodes); + return createManagedSet(entity, (Set)newVal); } @Override diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessor.java index abd1a8c0d..e3fb92a38 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessor.java @@ -16,15 +16,15 @@ public class SingleRelationshipFieldAccessor extends AbstractFieldAccessor { @Override public Object setValue(final NodeBacked entity, final Object newVal) { - checkUnderlyingNode(entity); + Node node=checkUnderlyingNode(entity); if (newVal == null) { - removeMissingRelationships(entity, Collections.emptySet()); + removeMissingRelationships(node, Collections.emptySet()); return null; } - final Set target=checkTargetIsSetOfNodebacked(Collections.singleton(newVal)); - checkNoCircularReference(entity,target); - removeMissingRelationships(entity, target); - createNewRelationshipsFrom(entity,target); + final Set target=checkTargetIsSetOfNodebacked(Collections.singleton(newVal)); + checkNoCircularReference(node,target); + removeMissingRelationships(node, target); + createAddedRelationships(node,target); return newVal; }