1 package eu.ehri.project.core.impl.neo4j;
2
3 import com.tinkerpop.blueprints.Edge;
4 import com.tinkerpop.blueprints.Vertex;
5 import com.tinkerpop.blueprints.VertexQuery;
6 import com.tinkerpop.blueprints.util.DefaultVertexQuery;
7 import com.tinkerpop.blueprints.util.MultiIterable;
8 import com.tinkerpop.blueprints.util.StringFactory;
9 import org.neo4j.graphdb.Direction;
10 import org.neo4j.graphdb.Label;
11 import org.neo4j.graphdb.Node;
12 import org.neo4j.graphdb.Relationship;
13 import org.neo4j.graphdb.RelationshipType;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collection;
18 import java.util.Iterator;
19
20
21 public class Neo4j2Vertex extends Neo4j2Element implements Vertex {
22
23 public Neo4j2Vertex(Node node, Neo4j2Graph graph) {
24 super(graph);
25 this.rawElement = node;
26
27 }
28
29 public Iterable<Edge> getEdges(com.tinkerpop.blueprints.Direction direction, String... labels) {
30 this.graph.autoStartTransaction(false);
31 if (direction.equals(com.tinkerpop.blueprints.Direction.OUT))
32 return new Neo4jVertexEdgeIterable(this.graph, (Node) this.rawElement, Direction.OUTGOING, labels);
33 else if (direction.equals(com.tinkerpop.blueprints.Direction.IN))
34 return new Neo4jVertexEdgeIterable(this.graph, (Node) this.rawElement, Direction.INCOMING, labels);
35 else
36 return new MultiIterable(Arrays.asList(new Neo4jVertexEdgeIterable(this.graph, (Node) this.rawElement, Direction.OUTGOING, labels), new Neo4jVertexEdgeIterable(this.graph, (Node) this.rawElement, Direction.INCOMING, labels)));
37 }
38
39 public Iterable<Vertex> getVertices(com.tinkerpop.blueprints.Direction direction, String... labels) {
40 this.graph.autoStartTransaction(false);
41 if (direction.equals(com.tinkerpop.blueprints.Direction.OUT))
42 return new Neo4jVertexVertexIterable(this.graph, (Node) this.rawElement, Direction.OUTGOING, labels);
43 else if (direction.equals(com.tinkerpop.blueprints.Direction.IN))
44 return new Neo4jVertexVertexIterable(this.graph, (Node) this.rawElement, Direction.INCOMING, labels);
45 else
46 return new MultiIterable(Arrays.asList(new Neo4jVertexVertexIterable(this.graph, (Node) this.rawElement, Direction.OUTGOING, labels), new Neo4jVertexVertexIterable(this.graph, (Node) this.rawElement, Direction.INCOMING, labels)));
47 }
48
49 public Edge addEdge(String label, Vertex vertex) {
50 return this.graph.addEdge(null, this, vertex, label);
51 }
52
53 public Collection<String> getLabels() {
54 this.graph.autoStartTransaction(false);
55 Collection<String> labels = new ArrayList<String>();
56 for (Label label : getRawVertex().getLabels()) {
57 labels.add(label.name());
58 }
59 return labels;
60 }
61
62 public void addLabel(String label) {
63 graph.autoStartTransaction(true);
64 getRawVertex().addLabel(Label.label(label));
65 }
66
67 public void removeLabel(String label) {
68 graph.autoStartTransaction(true);
69 getRawVertex().removeLabel(Label.label(label));
70 }
71
72 public VertexQuery query() {
73 this.graph.autoStartTransaction(false);
74 return new DefaultVertexQuery(this);
75 }
76
77 public boolean equals(Object object) {
78 return object instanceof Neo4j2Vertex && ((Neo4j2Vertex) object).getId().equals(this.getId());
79 }
80
81 public String toString() {
82 return StringFactory.vertexString(this);
83 }
84
85 public Node getRawVertex() {
86 return (Node) this.rawElement;
87 }
88
89 private class Neo4jVertexVertexIterable<T extends Vertex> implements Iterable<Neo4j2Vertex> {
90 private final Neo4j2Graph graph;
91 private final Node node;
92 private final Direction direction;
93 private final RelationshipType[] labels;
94
95 public Neo4jVertexVertexIterable(Neo4j2Graph graph, Node node, Direction direction, String... labels) {
96 this.graph = graph;
97 this.node = node;
98 this.direction = direction;
99 this.labels = new RelationshipType[labels.length];
100 for (int i = 0; i < labels.length; i++) {
101 this.labels[i] = RelationshipType.withName(labels[i]);
102 }
103 }
104
105 public Iterator<Neo4j2Vertex> iterator() {
106 graph.autoStartTransaction(false);
107 final Iterator<Relationship> itty;
108 if (labels.length > 0)
109 itty = node.getRelationships(direction, labels).iterator();
110 else
111 itty = node.getRelationships(direction).iterator();
112
113 return new Iterator<Neo4j2Vertex>() {
114 public Neo4j2Vertex next() {
115 graph.autoStartTransaction(false);
116 return new Neo4j2Vertex(itty.next().getOtherNode(node), graph);
117 }
118
119 public boolean hasNext() {
120 graph.autoStartTransaction(false);
121 return itty.hasNext();
122 }
123
124 public void remove() {
125 graph.autoStartTransaction(true);
126 itty.remove();
127 }
128 };
129 }
130 }
131
132 private class Neo4jVertexEdgeIterable<T extends Edge> implements Iterable<Neo4j2Edge> {
133
134 private final Neo4j2Graph graph;
135 private final Node node;
136 private final Direction direction;
137 private final RelationshipType[] labels;
138
139 public Neo4jVertexEdgeIterable(Neo4j2Graph graph, Node node, Direction direction, String... labels) {
140 this.graph = graph;
141 this.node = node;
142 this.direction = direction;
143 this.labels = new RelationshipType[labels.length];
144 for (int i = 0; i < labels.length; i++) {
145 this.labels[i] = RelationshipType.withName(labels[i]);
146 }
147 }
148
149 public Iterator<Neo4j2Edge> iterator() {
150 graph.autoStartTransaction(false);
151 final Iterator<Relationship> itty;
152 if (labels.length > 0)
153 itty = node.getRelationships(direction, labels).iterator();
154 else
155 itty = node.getRelationships(direction).iterator();
156
157 return new Iterator<Neo4j2Edge>() {
158 public Neo4j2Edge next() {
159 graph.autoStartTransaction(false);
160 return new Neo4j2Edge(itty.next(), graph);
161 }
162
163 public boolean hasNext() {
164 graph.autoStartTransaction(false);
165 return itty.hasNext();
166 }
167
168 public void remove() {
169 graph.autoStartTransaction(true);
170 itty.remove();
171 }
172 };
173 }
174 }
175
176 }