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 }