/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.graphdht.hashgraph; import java.io.Serializable; import java.util.*; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.ReturnableEvaluator; import org.neo4j.graphdb.StopEvaluator; import org.neo4j.graphdb.Traverser; import org.neo4j.graphdb.Traverser.Order; import org.neo4j.kernel.impl.traversal.InternalTraverserFactory; /** * @author alex */ public class SimpleNode extends SimplePrimitive implements Node, Serializable { /** * Lists the <code>Relationship</code>s associated to this <code>Node</code>. * Both Direction.OUTGOING AND Direction.INCOMING are included. */ List<Relationship> relationships = new ArrayList(); /** * Defines the <code>direction</code> of the <code>Relationship</code> in the same position. */ List<Direction> relDirection = new ArrayList(); transient InternalTraverserFactory traverserFactory = new InternalTraverserFactory(); public SimpleNode(long id, SimpleNodeManager service) { super(id, service); } public long getId() { return id; } public void delete() { this.dhtService.deleteNode(new Long(this.getId())); } public Iterable<Relationship> getRelationships() { return this.relationships; } public boolean hasRelationship() { return relationships.size() > 0 ? true : false; } public Iterable<Relationship> getRelationships(RelationshipType... types) { List<Relationship> r = new LinkedList(); for (Relationship rel : this.relationships) { for (RelationshipType relType : types) { if (rel.getType() == relType) { r.add(rel); } } } return r; } public boolean hasRelationship(RelationshipType... types) { List<Relationship> r = new LinkedList(); for (Relationship rel : this.relationships) { for (RelationshipType relType : types) { if (rel.getType() == relType) { return true; } } } return false; } public Iterable<Relationship> getRelationships(Direction dir) { Collection<Relationship> c = new ArrayList<Relationship>(); if (this.relationships.size() > 0) { if (dir == Direction.BOTH) { return this.getRelationships(); } else { for (Relationship rel : relationships) { if (rel.getStartNode().equals(this) && dir == Direction.OUTGOING) { c.add(rel); } else if (rel.getEndNode().equals(this) && dir == Direction.INCOMING) { c.add(rel); } } } } return c; } public boolean hasRelationship(Direction dir) { if (this.relationships.size() > 0) { if (dir == Direction.BOTH) { return true; } else { for (Relationship rel : relationships) { if (rel.getStartNode().equals(this) && dir == Direction.OUTGOING) { return true; } else if (rel.getEndNode().equals(this) && dir == Direction.INCOMING) { return true; } } } } return false; } public Iterable<Relationship> getRelationships(RelationshipType type, Direction dir) { Collection<Relationship> c = new ArrayList<Relationship>(); if (this.relationships.size() > 0) { if (dir == Direction.BOTH) { return this.getRelationships(type); } else { for (Relationship rel : relationships) { if (rel.getType() == type) { if (rel.getStartNode().equals(this) && dir == Direction.OUTGOING) { c.add(rel); } else if (rel.getEndNode().equals(this) && dir == Direction.INCOMING) { c.add(rel); } } } } } return c; } public boolean hasRelationship(RelationshipType type, Direction dir) { if (this.relationships.size() > 0) { if (dir == Direction.BOTH) { return this.hasRelationship(type); } else { for (Relationship rel : relationships) { if (rel.getType() == type) { if (rel.getStartNode().equals(this) && dir == Direction.OUTGOING) { return true; } else if (rel.getEndNode().equals(this) && dir == Direction.INCOMING) { return true; } } } } } return false; } public Relationship getSingleRelationship(RelationshipType type, Direction dir) { if (this.relationships.size() > 0) { if (dir == Direction.BOTH) { for (Relationship rel : this.relationships) { if (rel.getType() == type) { return rel; } } } else { for (Relationship rel : relationships) { if (rel.getType() == type) { if (rel.getStartNode().equals(this) && dir == Direction.OUTGOING) { return rel; } else if (rel.getEndNode().equals(this) && dir == Direction.INCOMING) { return rel; } } } } } return null; } public Relationship createRelationshipTo(Node otherNode, RelationshipType type) { //TODO this can be optimized by taking of the getRelationships(...) and doing everything in the foreach Iterable<Relationship> relIt = this.getRelationships(type, Direction.OUTGOING); //check if there are previous relationships for (Relationship rel : relationships) { if (rel.getEndNode().equals(otherNode) && rel.getType() == type) { return rel; //returns an existing relationship instead of creating a new one } } //else create relationship Relationship rel = null; try { rel = this.dhtService.createRelationship(this.id, otherNode.getId(), type); } catch (NullPointerException e) { System.out.println(this.dhtService); //@NULL This is the null e.printStackTrace(); } this.addRelationship(rel); return rel; } protected Relationship addRelationship(Relationship rel) { this.relationships.add(rel); return rel; } public Traverser traverse(Order traversalOrder, StopEvaluator stopEvaluator, ReturnableEvaluator returnableEvaluator, RelationshipType relationshipType, Direction direction) { if (direction == null) { throw new IllegalArgumentException("Null direction"); } if (relationshipType == null) { throw new IllegalArgumentException("Null relationship type"); } // rest of parameters will be validated in traverser package return this.traverserFactory.createTraverser(traversalOrder, this, relationshipType, direction, stopEvaluator, returnableEvaluator); } public Traverser traverse(Order traversalOrder, StopEvaluator stopEvaluator, ReturnableEvaluator returnableEvaluator, RelationshipType firstRelationshipType, Direction firstDirection, RelationshipType secondRelationshipType, Direction secondDirection) { if (firstDirection == null || secondDirection == null) { throw new IllegalArgumentException("Null direction, " + "firstDirection=" + firstDirection + "secondDirection=" + secondDirection); } if (firstRelationshipType == null || secondRelationshipType == null) { throw new IllegalArgumentException("Null rel type, " + "first=" + firstRelationshipType + "second=" + secondRelationshipType); } // rest of parameters will be validated in traverser package RelationshipType[] types = new RelationshipType[2]; Direction[] dirs = new Direction[2]; types[0] = firstRelationshipType; types[1] = secondRelationshipType; dirs[0] = firstDirection; dirs[1] = secondDirection; return this.traverserFactory.createTraverser(traversalOrder, this, types, dirs, stopEvaluator, returnableEvaluator); } public Traverser traverse(Order traversalOrder, StopEvaluator stopEvaluator, ReturnableEvaluator returnableEvaluator, Object... relationshipTypesAndDirections) { int length = relationshipTypesAndDirections.length; if ((length % 2) != 0 || length == 0) { throw new IllegalArgumentException("Variable argument should " + " consist of [RelationshipType,Direction] pairs"); } int elements = relationshipTypesAndDirections.length / 2; RelationshipType[] types = new RelationshipType[elements]; Direction[] dirs = new Direction[elements]; int j = 0; for (int i = 0; i < elements; i++) { Object relType = relationshipTypesAndDirections[j++]; if (!(relType instanceof RelationshipType)) { throw new IllegalArgumentException( "Expected RelationshipType at var args pos " + (j - 1) + ", found " + relType); } types[i] = (RelationshipType) relType; Object direction = relationshipTypesAndDirections[j++]; if (!(direction instanceof Direction)) { throw new IllegalArgumentException( "Expected Direction at var args pos " + (j - 1) + ", found " + direction); } dirs[i] = (Direction) direction; } return this.traverserFactory.createTraverser(traversalOrder, this, types, dirs, stopEvaluator, returnableEvaluator); } protected Relationship deleteRelationship(long aLong) { for (int i = 0; i < relationships.size(); i++) { if (this.relationships.get(i).getId() == aLong) { relDirection.remove(i); Relationship rel = this.relationships.remove(i); SimpleNode node = (SimpleNode) rel.getEndNode(); node.deleteRelationship(aLong); return rel; } } return null; } @Deprecated //cast from long to int might cause probles public int hashCode() { return (int) this.getId(); } public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final SimpleNode other = (SimpleNode) obj; if (this.getId() == other.getId()) { return true; } else { return false; } } }