changed field accessors to work on raw nodes

This commit is contained in:
Michael Hunger
2010-09-12 01:57:02 +02:00
parent 9017a95c31
commit 02d6201e03
3 changed files with 33 additions and 89 deletions

View File

@@ -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<Relationship> getRelationships(final NodeBacked entity) {
return entity.getUnderlyingNode().getRelationships(type, direction);
}
protected void removeMissingRelationships(NodeBacked entity, Set<NodeBacked> target) {
Set<Node> 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<Node> targetNodes) {
for ( Relationship relationship : node.getRelationships(type, direction) ) {
if (!targetNodes.remove(relationship.getOtherNode(node)))
relationship.delete();
}
}
private Set<Node> extractNodes(Set<NodeBacked> target) {
Set<Node> newNodes=new HashSet<Node>();
for (NodeBacked nodeBacked : target) {
newNodes.add(nodeBacked.getUnderlyingNode());
}
return newNodes;
}
protected void createNewRelationshipsFrom(NodeBacked entity, Set<NodeBacked> target) {
for (NodeBacked nodeBacked : target) {
createSingleRelationship(entity,nodeBacked);
protected void createAddedRelationships(Node node, Set<Node> targetNodes) {
for (Node targetNode : targetNodes) {
createSingleRelationship(node,targetNode);
}
}
protected void checkNoCircularReference(NodeBacked entity, Set<NodeBacked> target) {
if (target.contains(entity)) throw new InvalidDataAccessApiUsageException("Cannot create a circular reference to "+target);
protected void checkNoCircularReference(Node node, Set<Node> targetNodes) {
if (targetNodes.contains(node)) throw new InvalidDataAccessApiUsageException("Cannot create a circular reference to "+ targetNodes);
}
protected Set<NodeBacked> checkTargetIsSetOfNodebacked(Object newVal) {
protected Set<Node> checkTargetIsSetOfNodebacked(Object newVal) {
if (!(newVal instanceof Set)) {
throw new IllegalArgumentException("New value must be a Set, was: " + newVal.getClass());
}
Set<Node> nodes=new HashSet<Node>();
for (Object value : (Set<Object>) newVal) {
if (!(value instanceof NodeBacked)) {
throw new IllegalArgumentException("New value elements must be NodeBacked.");
}
nodes.add(((NodeBacked)value).getUnderlyingNode());
}
return (Set<NodeBacked>) newVal;
return nodes;
}
protected ManagedFieldAccessorSet<NodeBacked> createManagedSet(NodeBacked entity, Set<NodeBacked> result) {

View File

@@ -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.<NodeBacked>emptySet());
removeMissingRelationships(node, Collections.<Node>emptySet());
return null;
}
final Set<NodeBacked> target = checkTargetIsSetOfNodebacked(newVal);
checkNoCircularReference(entity,target);
removeMissingRelationships(entity, target);
createNewRelationshipsFrom(entity,target);
return createManagedSet(entity, target);
final Set<Node> targetNodes = checkTargetIsSetOfNodebacked(newVal);
checkNoCircularReference(node,targetNodes);
removeMissingRelationships(node, targetNodes);
createAddedRelationships(node,targetNodes);
return createManagedSet(entity, (Set<NodeBacked>)newVal);
}
@Override

View File

@@ -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.<NodeBacked>emptySet());
removeMissingRelationships(node, Collections.<Node>emptySet());
return null;
}
final Set<NodeBacked> target=checkTargetIsSetOfNodebacked(Collections.singleton(newVal));
checkNoCircularReference(entity,target);
removeMissingRelationships(entity, target);
createNewRelationshipsFrom(entity,target);
final Set<Node> target=checkTargetIsSetOfNodebacked(Collections.singleton(newVal));
checkNoCircularReference(node,target);
removeMissingRelationships(node, target);
createAddedRelationships(node,target);
return newVal;
}