Mercurial > hg > AnnotationManagerN4J
comparison src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java @ 32:0731c4549065
UI for editing groups and persons works now. (still no authorisation!)
author | casties |
---|---|
date | Tue, 25 Sep 2012 21:59:21 +0200 |
parents | 3be0ebb6d5ad |
children | 86bb29132ba6 |
comparison
equal
deleted
inserted
replaced
30:05b631a084d0 | 32:0731c4549065 |
---|---|
2 * | 2 * |
3 */ | 3 */ |
4 package de.mpiwg.itgroup.annotations.neo4j; | 4 package de.mpiwg.itgroup.annotations.neo4j; |
5 | 5 |
6 import java.util.ArrayList; | 6 import java.util.ArrayList; |
7 import java.util.Arrays; | |
7 import java.util.Calendar; | 8 import java.util.Calendar; |
8 import java.util.HashSet; | 9 import java.util.HashSet; |
9 import java.util.List; | 10 import java.util.List; |
10 import java.util.Set; | 11 import java.util.Set; |
11 | 12 |
25 import de.mpiwg.itgroup.annotations.Group; | 26 import de.mpiwg.itgroup.annotations.Group; |
26 import de.mpiwg.itgroup.annotations.Person; | 27 import de.mpiwg.itgroup.annotations.Person; |
27 import de.mpiwg.itgroup.annotations.Tag; | 28 import de.mpiwg.itgroup.annotations.Tag; |
28 | 29 |
29 /** | 30 /** |
31 * Neo4J based Annotation store. | |
32 * | |
30 * @author casties | 33 * @author casties |
31 * | 34 * |
32 */ | 35 */ |
33 public class AnnotationStore { | 36 public class AnnotationStore { |
34 | 37 |
37 protected GraphDatabaseService graphDb; | 40 protected GraphDatabaseService graphDb; |
38 | 41 |
39 public static enum NodeTypes { | 42 public static enum NodeTypes { |
40 ANNOTATION, PERSON, TARGET, GROUP, TAG | 43 ANNOTATION, PERSON, TARGET, GROUP, TAG |
41 } | 44 } |
45 | |
46 // types of nodes that should not be automatically deleted. | |
47 public Set<String> permanentNodeTypes = new HashSet<String>(Arrays.asList("PERSON", "GROUP", "TAG")); | |
42 | 48 |
43 protected List<Index<Node>> nodeIndexes; | 49 protected List<Index<Node>> nodeIndexes; |
44 | 50 |
45 public static enum RelationTypes implements RelationshipType { | 51 public static enum RelationTypes implements RelationshipType { |
46 ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ, MEMBER_OF, HAS_TAG | 52 ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ, MEMBER_OF, HAS_TAG |
98 } | 104 } |
99 return actors; | 105 return actors; |
100 } | 106 } |
101 | 107 |
102 /** | 108 /** |
103 * Returns List of Groups. | 109 * Returns List of Groups. Key has to be indexed. |
104 * Key has to be indexed. | |
105 * | 110 * |
106 * @param key | 111 * @param key |
107 * @param query | 112 * @param query |
108 * @return | 113 * @return |
109 */ | 114 */ |
119 Actor group = createActorFromNode(groupNode); | 124 Actor group = createActorFromNode(groupNode); |
120 groups.add((Group) group); | 125 groups.add((Group) group); |
121 } | 126 } |
122 return groups; | 127 return groups; |
123 } | 128 } |
124 | 129 |
125 | 130 /** |
126 /** | 131 * Returns List of Tags. Key has to be indexed. |
127 * Returns List of Tags. | |
128 * Key has to be indexed. | |
129 * | 132 * |
130 * @param key | 133 * @param key |
131 * @param query | 134 * @param query |
132 * @return | 135 * @return |
133 */ | 136 */ |
144 tags.add(tag); | 147 tags.add(tag); |
145 } | 148 } |
146 return tags; | 149 return tags; |
147 } | 150 } |
148 | 151 |
149 | 152 /** |
150 /** | |
151 * Returns List of Groups the person is member of. | 153 * Returns List of Groups the person is member of. |
152 * | 154 * |
153 * @param person | 155 * @param person |
154 * @return | 156 * @return |
155 */ | 157 */ |
210 } | 212 } |
211 members.add((Person) member); | 213 members.add((Person) member); |
212 } | 214 } |
213 return members; | 215 return members; |
214 } | 216 } |
215 | 217 |
216 /** | 218 /** |
217 * Add Person newMember to Group group. | 219 * Add Person newMember to Group group. |
218 * | 220 * |
219 * @param group | 221 * @param group |
220 * @param member | 222 * @param member |
227 getOrCreateRelation(pn, RelationTypes.MEMBER_OF, gn); | 229 getOrCreateRelation(pn, RelationTypes.MEMBER_OF, gn); |
228 addedMember = member; | 230 addedMember = member; |
229 } | 231 } |
230 return addedMember; | 232 return addedMember; |
231 } | 233 } |
232 | 234 |
233 /** | 235 /** |
234 * Delete Person oldMember from Group group. | 236 * Delete Person oldMember from Group group. |
235 * | 237 * |
236 * @param group | 238 * @param group |
237 * @param member | 239 * @param member |
238 */ | 240 */ |
239 public void deleteGroupMember(Group group, Person member) { | 241 public void deleteGroupMember(Group group, Person member) { |
240 Node gn = getActorNode(group); | 242 Node gn = getActorNode(group); |
243 Node pn = getActorNode(member); | |
241 Iterable<Relationship> rels = gn.getRelationships(RelationTypes.MEMBER_OF); | 244 Iterable<Relationship> rels = gn.getRelationships(RelationTypes.MEMBER_OF); |
242 for (Relationship rel : rels) { | 245 for (Relationship rel : rels) { |
243 Node mn = rel.getStartNode(); | 246 Node mn = rel.getStartNode(); |
244 if (mn.equals(member)) { | 247 if (mn.equals(pn)) { |
245 rel.delete(); | 248 Transaction tx = graphDb.beginTx(); |
249 try { | |
250 rel.delete(); | |
251 tx.success(); | |
252 } finally { | |
253 tx.finish(); | |
254 } | |
246 // there should be only one | 255 // there should be only one |
247 break; | 256 break; |
248 } | 257 } |
249 } | 258 } |
250 } | 259 } |
251 | 260 |
252 /** | 261 /** |
253 * Returns the stored Actor matching the given one. | 262 * Returns the stored Actor matching the given one. |
254 * | 263 * |
255 * @param actor | 264 * @param actor |
256 * @return | 265 * @return |
257 */ | 266 */ |
258 public Actor getActor(Actor actor) { | 267 public Actor getActor(Actor actor) { |
259 Node actorNode = getActorNode(actor); | 268 Node actorNode = getActorNode(actor); |
260 Actor storedActor = createActorFromNode(actorNode); | 269 Actor storedActor = createActorFromNode(actorNode); |
261 return storedActor; | 270 return storedActor; |
262 } | 271 } |
263 | 272 |
264 /** | 273 /** |
265 * Stores an Actor (Person or Group). Creates a new actor Node or returns an existing one. | 274 * Stores an Actor (Person or Group). Creates a new actor Node or update an |
275 * existing one. | |
266 * | 276 * |
267 * @param actor | 277 * @param actor |
268 * @return | 278 * @return |
269 */ | 279 */ |
270 public Actor storeActor(Actor actor) { | 280 public Actor storeActor(Actor actor) { |
271 Node actorNode = getOrCreateActorNode(actor); | 281 Node actorNode = getOrCreateActorNode(actor); |
272 Actor storedActor = createActorFromNode(actorNode); | 282 Transaction tx = graphDb.beginTx(); |
273 return storedActor; | 283 try { |
274 } | 284 // id |
275 | 285 String id = actor.getId(); |
286 if (id != null) { | |
287 actorNode.setProperty("id", id); | |
288 } | |
289 // name | |
290 String name = actor.getName(); | |
291 if (name != null) { | |
292 actorNode.setProperty("name", name); | |
293 } | |
294 // uri | |
295 String uri = actor.getUri(); | |
296 if (uri != null) { | |
297 actorNode.setProperty("uri", uri); | |
298 } | |
299 tx.success(); | |
300 } finally { | |
301 tx.finish(); | |
302 } | |
303 Actor storedActor = createActorFromNode(actorNode); | |
304 return storedActor; | |
305 } | |
306 | |
307 /** | |
308 * Deletes the given Actor. | |
309 * | |
310 * @param actor | |
311 */ | |
312 public void deleteActor(Actor actor) { | |
313 String uri = actor.getUriString(); | |
314 Index<Node> idx; | |
315 if (actor.isGroup()) { | |
316 idx = getNodeIndex(NodeTypes.GROUP); | |
317 } else { | |
318 idx = getNodeIndex(NodeTypes.PERSON); | |
319 } | |
320 Node actorNode = idx.get("uri", uri).getSingle(); | |
321 if (actorNode != null) { | |
322 // delete relations | |
323 Transaction tx = graphDb.beginTx(); | |
324 try { | |
325 for (Relationship rel : actorNode.getRelationships()) { | |
326 rel.delete(); | |
327 } | |
328 if (!actorNode.hasRelationship()) { | |
329 // this shouldn't happen | |
330 deleteNode(actorNode); | |
331 } else { | |
332 logger.error("deleteActor: unable to delete: Node still has relations."); | |
333 } | |
334 tx.success(); | |
335 } finally { | |
336 tx.finish(); | |
337 } | |
338 } | |
339 } | |
340 | |
276 /** | 341 /** |
277 * Returns the Annotation with the given id. | 342 * Returns the Annotation with the given id. |
278 * | 343 * |
279 * @param id | 344 * @param id |
280 * @return | 345 * @return |
373 * | 438 * |
374 * @param actorNode | 439 * @param actorNode |
375 * @return | 440 * @return |
376 */ | 441 */ |
377 protected Actor createActorFromNode(Node actorNode) { | 442 protected Actor createActorFromNode(Node actorNode) { |
443 if (actorNode == null) return null; | |
378 String id = (String) actorNode.getProperty("id", null); | 444 String id = (String) actorNode.getProperty("id", null); |
379 String uri = (String) actorNode.getProperty("uri", null); | 445 String uri = (String) actorNode.getProperty("uri", null); |
380 String name = (String) actorNode.getProperty("name", null); | 446 String name = (String) actorNode.getProperty("name", null); |
381 String type = (String) actorNode.getProperty("TYPE", null); | 447 String type = (String) actorNode.getProperty("TYPE", null); |
382 if (type != null && type.equals("PERSON")) { | 448 if (type != null && type.equals("PERSON")) { |
384 } else if (type != null && type.equals("GROUP")) { | 450 } else if (type != null && type.equals("GROUP")) { |
385 return new Group(id, uri, name); | 451 return new Group(id, uri, name); |
386 } | 452 } |
387 return null; | 453 return null; |
388 } | 454 } |
389 | 455 |
390 public Tag createTagFromNode(Node tagNode) { | 456 public Tag createTagFromNode(Node tagNode) { |
391 String name = (String) tagNode.getProperty("name", null); | 457 if (tagNode == null) return null; |
392 String uri = (String) tagNode.getProperty("uri", null); | 458 String name = (String) tagNode.getProperty("name", null); |
393 String id = (String) tagNode.getProperty("id", null); | 459 String uri = (String) tagNode.getProperty("uri", null); |
394 | 460 String id = (String) tagNode.getProperty("id", null); |
395 return new Tag(id, uri, name); | 461 |
396 | 462 return new Tag(id, uri, name); |
397 } | 463 |
398 | 464 } |
399 | 465 |
400 /** | 466 /** |
401 * Store a new annotation in the store or update an existing one. Returns | 467 * Store a new annotation in the store or update an existing one. Returns |
402 * the stored annotation. | 468 * the stored annotation. |
403 * | 469 * |
509 } | 575 } |
510 if (!newTags.isEmpty()) { | 576 if (!newTags.isEmpty()) { |
511 // still tags to add | 577 // still tags to add |
512 for (String tag : newTags) { | 578 for (String tag : newTags) { |
513 // create new tag | 579 // create new tag |
514 Node tagNode = getOrCreateTagNode(new Tag(null,null,tag)); | 580 Node tagNode = getOrCreateTagNode(new Tag(null, null, tag)); |
515 getOrCreateRelation(annotNode, RelationTypes.HAS_TAG, tagNode); | 581 getOrCreateRelation(annotNode, RelationTypes.HAS_TAG, tagNode); |
516 } | 582 } |
517 } | 583 } |
518 | 584 |
519 } | 585 } |
531 /** | 597 /** |
532 * Deletes the annotation with the given id. | 598 * Deletes the annotation with the given id. |
533 * | 599 * |
534 * @param id | 600 * @param id |
535 */ | 601 */ |
536 public void deleteById(String id) { | 602 public void deleteAnnotationById(String id) { |
537 Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle(); | 603 Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle(); |
538 if (annotNode != null) { | 604 if (annotNode != null) { |
539 // delete related objects | 605 // delete related objects |
540 Transaction tx = graphDb.beginTx(); | 606 Transaction tx = graphDb.beginTx(); |
541 try { | 607 try { |
542 for (Relationship rel : annotNode.getRelationships()) { | 608 for (Relationship rel : annotNode.getRelationships()) { |
543 // delete relation and the related node if it has no other | 609 // delete relation and the related node if it has no other |
544 // relations | 610 // relations and is not permanent |
545 Node other = rel.getOtherNode(annotNode); | 611 Node other = rel.getOtherNode(annotNode); |
546 rel.delete(); | 612 rel.delete(); |
547 if (!other.hasRelationship()) { | 613 if (!(other.hasRelationship() || permanentNodeTypes.contains(other.getProperty("TYPE", null)))) { |
548 deleteNode(other); | 614 deleteNode(other); |
549 } | 615 } |
550 } | 616 } |
551 if (!annotNode.hasRelationship()) { | 617 if (!annotNode.hasRelationship()) { |
552 deleteNode(annotNode); | 618 deleteNode(annotNode); |
567 * @param userUri | 633 * @param userUri |
568 * @param limit | 634 * @param limit |
569 * @param offset | 635 * @param offset |
570 * @return | 636 * @return |
571 */ | 637 */ |
572 public List<Annotation> searchByUriUser(String targetUri, String userUri, String limit, String offset) { | 638 public List<Annotation> searchAnnotationByUriUser(String targetUri, String userUri, String limit, String offset) { |
573 List<Annotation> annotations = new ArrayList<Annotation>(); | 639 List<Annotation> annotations = new ArrayList<Annotation>(); |
574 if (targetUri != null) { | 640 if (targetUri != null) { |
575 // there should be only one | 641 // there should be only one |
576 Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri).getSingle(); | 642 Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri).getSingle(); |
577 if (target != null) { | 643 if (target != null) { |
690 } | 756 } |
691 IndexHits<Node> persons = idx.get("uri", uri); | 757 IndexHits<Node> persons = idx.get("uri", uri); |
692 Node person = persons.getSingle(); | 758 Node person = persons.getSingle(); |
693 return person; | 759 return person; |
694 } | 760 } |
695 | 761 |
696 protected Node getOrCreateActorNode(Actor actor) { | 762 protected Node getOrCreateActorNode(Actor actor) { |
697 // Person/Group is identified by URI or id | 763 // Person/Group is identified by URI or id |
698 String uri = actor.getUriString(); | 764 String uri = actor.getUriString(); |
699 String name = actor.getName(); | 765 String name = actor.getName(); |
700 String id = actor.getId(); | 766 String id = actor.getId(); |
743 try { | 809 try { |
744 tag = graphDb.createNode(); | 810 tag = graphDb.createNode(); |
745 tag.setProperty("TYPE", NodeTypes.TAG.name()); | 811 tag.setProperty("TYPE", NodeTypes.TAG.name()); |
746 tag.setProperty("name", tagname); | 812 tag.setProperty("name", tagname); |
747 idx.add(tag, "name", tagname); | 813 idx.add(tag, "name", tagname); |
748 | 814 |
749 tag.setProperty("id", inTag.getId()); | 815 tag.setProperty("id", inTag.getId()); |
750 tag.setProperty("uri", inTag.getUri()); | 816 tag.setProperty("uri", inTag.getUri()); |
751 idx.add(tag, "uri", inTag.getUri()); | 817 idx.add(tag, "uri", inTag.getUri()); |
752 | 818 |
753 tx.success(); | 819 tx.success(); |
754 } finally { | 820 } finally { |
755 tx.finish(); | 821 tx.finish(); |
756 } | 822 } |
757 } | 823 } |
851 | 917 |
852 return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time); | 918 return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time); |
853 | 919 |
854 } | 920 } |
855 | 921 |
856 public List<Annotation> getAnnotationsByTag(String tagUri) { | 922 public List<Annotation> getAnnotationsByTag(String tagUri) { |
857 | 923 |
858 ArrayList<Annotation> ret = new ArrayList<Annotation>(); | 924 ArrayList<Annotation> ret = new ArrayList<Annotation>(); |
859 Node tag = getTagNodeByUri(tagUri); | 925 Node tag = getTagNodeByUri(tagUri); |
860 | 926 |
861 | 927 Iterable<Relationship> rels = tag.getRelationships(Direction.INCOMING, RelationTypes.HAS_TAG); |
862 Iterable<Relationship> rels = tag.getRelationships(Direction.INCOMING,RelationTypes.HAS_TAG); | 928 |
863 | 929 for (Relationship rel : rels) { |
864 for (Relationship rel:rels){ | 930 Node node = rel.getStartNode(); |
865 Node node = rel.getStartNode(); | 931 ret.add(createAnnotationFromNode(node)); |
866 ret.add(createAnnotationFromNode(node)); | 932 |
867 | 933 } |
868 } | 934 return ret; |
869 return ret; | 935 } |
870 } | |
871 | 936 |
872 } | 937 } |