source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java @ 31:9f653697437e

Last change on this file since 31:9f653697437e was 31:9f653697437e, checked in by dwinter, 12 years ago

annotationbrowser

File size: 29.5 KB
Line 
1/**
2 *
3 */
4package de.mpiwg.itgroup.annotations.neo4j;
5
6import java.util.ArrayList;
7import java.util.Calendar;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Set;
11
12import org.apache.log4j.Logger;
13import org.neo4j.graphdb.Direction;
14import org.neo4j.graphdb.GraphDatabaseService;
15import org.neo4j.graphdb.Node;
16import org.neo4j.graphdb.Relationship;
17import org.neo4j.graphdb.RelationshipType;
18import org.neo4j.graphdb.Transaction;
19import org.neo4j.graphdb.index.Index;
20import org.neo4j.graphdb.index.IndexHits;
21
22import de.mpiwg.itgroup.annotations.Actor;
23import de.mpiwg.itgroup.annotations.Annotation;
24import de.mpiwg.itgroup.annotations.Annotation.FragmentTypes;
25import de.mpiwg.itgroup.annotations.Group;
26import de.mpiwg.itgroup.annotations.Person;
27import de.mpiwg.itgroup.annotations.Tag;
28
29/**
30 * @author casties
31 *
32 */
33public class AnnotationStore {
34
35    protected static Logger logger = Logger.getLogger(AnnotationStore.class);
36
37    protected GraphDatabaseService graphDb;
38
39    public static enum NodeTypes {
40        ANNOTATION, PERSON, TARGET, GROUP, TAG
41    }
42
43    protected List<Index<Node>> nodeIndexes;
44
45    public static enum RelationTypes implements RelationshipType {
46        ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ, MEMBER_OF, HAS_TAG
47    }
48
49    public static String ANNOTATION_URI_BASE = "http://entities.mpiwg-berlin.mpg.de/annotations/";
50
51    public AnnotationStore(GraphDatabaseService graphDb) {
52        super();
53        this.graphDb = graphDb;
54        nodeIndexes = new ArrayList<Index<Node>>(5);
55        // List.set(enum.ordinal(), val) seems not to work.
56        nodeIndexes.add(NodeTypes.ANNOTATION.ordinal(), graphDb.index().forNodes("annotations"));
57        nodeIndexes.add(NodeTypes.PERSON.ordinal(), graphDb.index().forNodes("persons"));
58        nodeIndexes.add(NodeTypes.TARGET.ordinal(), graphDb.index().forNodes("targets"));
59        nodeIndexes.add(NodeTypes.GROUP.ordinal(), graphDb.index().forNodes("groups"));
60        nodeIndexes.add(NodeTypes.TAG.ordinal(), graphDb.index().forNodes("tags"));
61    }
62
63    protected Index<Node> getNodeIndex(NodeTypes type) {
64        return nodeIndexes.get(type.ordinal());
65    }
66
67    /**
68     * @param userUri
69     * @return
70     */
71    public Node getPersonNodeByUri(String userUri) {
72        if (userUri == null) return null;
73        Node person = getNodeIndex(NodeTypes.PERSON).get("uri", userUri).getSingle();
74        return person;
75    }
76
77    /**
78     * @param tagUri
79     * @return
80     */
81    public Node getTagNodeByUri(String tagUri) {
82        if (tagUri == null) return null;
83        Node person = getNodeIndex(NodeTypes.TAG).get("uri", tagUri).getSingle();
84        return person;
85    }
86
87   
88   
89    public List<Actor> getActors(String key, String query, NodeTypes type) {
90        ArrayList<Actor> actors = new ArrayList<Actor>();
91        Index<Node> idx = getNodeIndex(type);
92        if (key == null) {
93            key = "uri";
94            query = "*";
95        }
96        IndexHits<Node> actorNodes = idx.query(key, query);
97        for (Node actorNode : actorNodes) {
98            Actor actor = createActorFromNode(actorNode);
99            actors.add(actor);
100        }
101        return actors;
102    }
103
104    /**
105     * Returns List of Groups.
106     * Key has to be indexed.
107     *
108     * @param key
109     * @param query
110     * @return
111     */
112    public List<Group> getGroups(String key, String query) {
113        ArrayList<Group> groups = new ArrayList<Group>();
114        Index<Node> idx = getNodeIndex(NodeTypes.GROUP);
115        if (key == null) {
116            key = "uri";
117            query = "*";
118        }
119        IndexHits<Node> groupNodes = idx.query(key, query);
120        for (Node groupNode : groupNodes) {
121            Actor group = createActorFromNode(groupNode);
122            groups.add((Group) group);
123        }
124        return groups;
125    }
126   
127   
128    /**
129     * Returns List of Annotations.
130     * Key has to be indexed.
131     *
132     * @param key
133     * @param query
134     * @return
135     */
136    public List<Annotation> getAnnotations(String key, String query) {
137        ArrayList<Annotation> annotations = new ArrayList<Annotation>();
138        Index<Node> idx = getNodeIndex(NodeTypes.ANNOTATION);
139        if (key == null) {
140            key = "id";
141            query = "*";
142        }
143        IndexHits<Node> annotNodes = idx.query(key, query);
144        for (Node annotNode : annotNodes) {
145            Annotation annotation = createAnnotationFromNode(annotNode);
146            annotations.add(annotation);
147        }
148        return annotations;
149    }
150
151 
152   
153    /**
154     * Returns List of Tags.
155     * Key has to be indexed.
156     *
157     * @param key
158     * @param query
159     * @return
160     */
161    public List<Tag> getTags(String key, String query) {
162        ArrayList<Tag> tags = new ArrayList<Tag>();
163        Index<Node> idx = getNodeIndex(NodeTypes.TAG);
164        if (key == null) {
165            key = "uri";
166            query = "*";
167        }
168        IndexHits<Node> groupNodes = idx.query(key, query);
169        for (Node groupNode : groupNodes) {
170            Tag tag = createTagFromNode(groupNode);
171            tags.add(tag);
172        }
173        return tags;
174    }
175
176 
177   /**
178     * Returns List of Groups the person is member of.
179     *
180     * @param person
181     * @return
182     */
183    public List<Group> getGroupsForPersonNode(Node person) {
184        ArrayList<Group> groups = new ArrayList<Group>();
185        Iterable<Relationship> rels = person.getRelationships(RelationTypes.MEMBER_OF);
186        for (Relationship rel : rels) {
187            Node groupNode = rel.getEndNode();
188            Actor group = createActorFromNode(groupNode);
189            // make sure we're getting a group
190            if (!(group instanceof Group)) {
191                logger.error("target of MEMBER_OF is not GROUP! rel=" + rel);
192                continue;
193            }
194            groups.add((Group) group);
195        }
196        return groups;
197    }
198
199    /**
200     * Returns if person with uri is in Group group.
201     *
202     * @param person
203     * @param group
204     * @return
205     */
206    public boolean isPersonInGroup(Person person, Group group) {
207        Node pn = getPersonNodeByUri(person.getUriString());
208        if (pn == null) return false;
209        // optimized version of getGroupsForPersonNode
210        Iterable<Relationship> rels = pn.getRelationships(RelationTypes.MEMBER_OF);
211        for (Relationship rel : rels) {
212            Node gn = rel.getEndNode();
213            if (gn.getProperty("uri", "").equals(group.getUriString()) || gn.getProperty("id", "").equals(group.getId())) {
214                return true;
215            }
216        }
217        return false;
218    }
219
220    /**
221     * Returns the members of the group.
222     *
223     * @param group
224     * @return
225     */
226    public List<Person> getMembersOfGroup(Group group) {
227        ArrayList<Person> members = new ArrayList<Person>();
228        Node gn = getActorNode(group);
229        Iterable<Relationship> rels = gn.getRelationships(RelationTypes.MEMBER_OF);
230        for (Relationship rel : rels) {
231            Node memberNode = rel.getStartNode();
232            Actor member = createActorFromNode(memberNode);
233            // make sure we're getting a group
234            if (!(member instanceof Person)) {
235                logger.error("source of MEMBER_OF is not PERSON! rel=" + rel);
236                continue;
237            }
238            members.add((Person) member);
239        }
240        return members;
241    }
242   
243    /**
244     * Add Person newMember to Group group.
245     *
246     * @param group
247     * @param member
248     */
249    public Person addGroupMember(Group group, Person member) {
250        Node gn = getActorNode(group);
251        Node pn = getActorNode(member);
252        Person addedMember = null;
253        if (gn != null && pn != null) {
254            getOrCreateRelation(pn, RelationTypes.MEMBER_OF, gn);
255            addedMember = member;
256        }
257        return addedMember;
258    }
259   
260    /**
261     * Delete Person oldMember from Group group.
262     *
263     * @param group
264     * @param member
265     */
266    public void deleteGroupMember(Group group, Person member) {
267        Node gn = getActorNode(group);
268        Iterable<Relationship> rels = gn.getRelationships(RelationTypes.MEMBER_OF);
269        for (Relationship rel : rels) {
270            Node mn = rel.getStartNode();
271            if (mn.equals(member)) {
272                rel.delete();
273                // there should be only one
274                break;
275            }
276        }       
277    }
278   
279    /**
280     * Returns the stored Actor matching the given one.
281     *
282     * @param actor
283     * @return
284     */
285    public Actor getActor(Actor actor) {
286        Node actorNode = getActorNode(actor);
287        Actor storedActor = createActorFromNode(actorNode);
288        return storedActor;
289    }
290   
291    /**
292     * Stores an Actor (Person or Group). Creates a new actor Node or returns an existing one.
293     *
294     * @param actor
295     * @return
296     */
297    public Actor storeActor(Actor actor) {
298        Node actorNode = getOrCreateActorNode(actor);
299        Actor storedActor = createActorFromNode(actorNode);
300        return storedActor;
301    }
302   
303    /**
304     * Returns the Annotation with the given id.
305     *
306     * @param id
307     * @return
308     */
309    public Annotation getAnnotationById(String id) {
310        Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle();
311        Annotation annot = createAnnotationFromNode(annotNode);
312        return annot;
313    }
314
315    /**
316     * Returns an Annotation object from an annotation-Node.
317     *
318     * @param annotNode
319     * @return
320     */
321    public Annotation createAnnotationFromNode(Node annotNode) {
322        Annotation annot = new Annotation();
323        annot.setUri((String) annotNode.getProperty("id", null));
324        annot.setBodyText((String) annotNode.getProperty("bodyText", null));
325        annot.setBodyUri((String) annotNode.getProperty("bodyUri", null));
326        /*
327         * get annotation target from relation
328         */
329        Relationship targetRel = getRelation(annotNode, RelationTypes.ANNOTATES, null);
330        if (targetRel != null) {
331            Node target = targetRel.getEndNode();
332            annot.setTargetBaseUri((String) target.getProperty("uri", null));
333        } else {
334            logger.error("annotation " + annotNode + " has no target node!");
335        }
336        annot.setTargetFragment((String) annotNode.getProperty("targetFragment", null));
337        String ft = (String) annotNode.getProperty("fragmentType", null);
338        if (ft != null) {
339            annot.setFragmentType(FragmentTypes.valueOf(ft));
340        }
341        /*
342         * get creator from relation
343         */
344        Relationship creatorRel = getRelation(annotNode, RelationTypes.CREATED, null);
345        if (creatorRel != null) {
346            Node creatorNode = creatorRel.getStartNode();
347            Actor creator = createActorFromNode(creatorNode);
348            annot.setCreator(creator);
349        } else {
350            logger.error("annotation " + annotNode + " has no creator node!");
351        }
352        /*
353         * get creation date
354         */
355        annot.setCreated((String) annotNode.getProperty("created", null));
356        /*
357         * get permissions
358         */
359        Relationship adminRel = getRelation(annotNode, RelationTypes.PERMITS_ADMIN, null);
360        if (adminRel != null) {
361            Node adminNode = adminRel.getEndNode();
362            Actor admin = createActorFromNode(adminNode);
363            annot.setAdminPermission(admin);
364        }
365        Relationship deleteRel = getRelation(annotNode, RelationTypes.PERMITS_DELETE, null);
366        if (deleteRel != null) {
367            Node deleteNode = deleteRel.getEndNode();
368            Actor delete = createActorFromNode(deleteNode);
369            annot.setDeletePermission(delete);
370        }
371        Relationship updateRel = getRelation(annotNode, RelationTypes.PERMITS_UPDATE, null);
372        if (updateRel != null) {
373            Node updateNode = updateRel.getEndNode();
374            Actor update = createActorFromNode(updateNode);
375            annot.setUpdatePermission(update);
376        }
377        Relationship readRel = getRelation(annotNode, RelationTypes.PERMITS_READ, null);
378        if (readRel != null) {
379            Node readNode = readRel.getEndNode();
380            Actor read = createActorFromNode(readNode);
381            annot.setReadPermission(read);
382        }
383        /*
384         * get tags
385         */
386        Set<String> tags = new HashSet<String>();
387        for (Relationship rel : annotNode.getRelationships(RelationTypes.HAS_TAG)) {
388            String tag = (String) rel.getEndNode().getProperty("name", null);
389            if (tag != null) {
390                tags.add(tag);
391            }
392        }
393        annot.setTags(tags);
394
395        return annot;
396    }
397
398    /**
399     * Returns an Actor object from a node.
400     *
401     * @param actorNode
402     * @return
403     */
404    protected Actor createActorFromNode(Node actorNode) {
405        String id = (String) actorNode.getProperty("id", null);
406        String uri = (String) actorNode.getProperty("uri", null);
407        String name = (String) actorNode.getProperty("name", null);
408        String type = (String) actorNode.getProperty("TYPE", null);
409        if (type != null && type.equals("PERSON")) {
410            return new Person(id, uri, name);
411        } else if (type != null && type.equals("GROUP")) {
412            return new Group(id, uri, name);
413        }
414        return null;
415    }
416   
417    public Tag createTagFromNode(Node tagNode) {
418        String name = (String) tagNode.getProperty("name", null);
419        String uri = (String) tagNode.getProperty("uri", null);
420        String id = (String) tagNode.getProperty("id", null);
421       
422        return new Tag(id, uri, name);
423               
424        }
425
426
427    /**
428     * Store a new annotation in the store or update an existing one. Returns
429     * the stored annotation.
430     *
431     * @param annot
432     * @return
433     */
434    public Annotation storeAnnotation(Annotation annot) {
435        Node annotNode = null;
436        Transaction tx = graphDb.beginTx();
437        try {
438            /*
439             * create or get the annotation
440             */
441            String id = annot.getUri();
442            if (id == null) {
443                id = createRessourceURI("annot:");
444            }
445            annotNode = getOrCreateAnnotationNode(id);
446
447            /*
448             * the annotation body
449             */
450            String bodyText = annot.getBodyText();
451            if (bodyText != null) {
452                annotNode.setProperty("bodyText", bodyText);
453            }
454            String bodyUri = annot.getBodyUri();
455            if (bodyUri != null) {
456                annotNode.setProperty("bodyUri", bodyUri);
457            }
458
459            /*
460             * the annotation target
461             */
462            String targetBaseUri = annot.getTargetBaseUri();
463            if (targetBaseUri != null) {
464                Node target = getOrCreateTargetNode(targetBaseUri);
465                getOrCreateRelation(annotNode, RelationTypes.ANNOTATES, target);
466            }
467
468            /*
469             * The fragment part of the annotation target.
470             */
471            String targetFragment = annot.getTargetFragment();
472            FragmentTypes fragmentType = annot.getFragmentType();
473            if (targetFragment != null) {
474                annotNode.setProperty("targetFragment", targetFragment);
475                annotNode.setProperty("fragmentType", fragmentType.name());
476            }
477
478            /*
479             * The creator of this annotation.
480             */
481            Actor creator = annot.getCreator();
482            if (creator != null) {
483                Node creatorNode = getOrCreateActorNode(creator);
484                getOrCreateRelation(creatorNode, RelationTypes.CREATED, annotNode);
485            }
486
487            /*
488             * The creation date of this annotation.
489             */
490            String created = annot.getCreated();
491            if (created != null) {
492                annotNode.setProperty("created", created);
493            }
494
495            /*
496             * Permissions for this annotation.
497             */
498            setPermissionRelation(annotNode, RelationTypes.PERMITS_ADMIN, annot.getAdminPermission());
499            setPermissionRelation(annotNode, RelationTypes.PERMITS_DELETE, annot.getDeletePermission());
500            setPermissionRelation(annotNode, RelationTypes.PERMITS_UPDATE, annot.getUpdatePermission());
501            setPermissionRelation(annotNode, RelationTypes.PERMITS_READ, annot.getReadPermission());
502
503            /*
504             * Tags on this annotation.
505             */
506            Set<String> newTags = annot.getTags();
507            // we ignore existing tags if tags == null
508            if (newTags != null) {
509                List<Relationship> oldHasTags = new ArrayList<Relationship>();
510                for (Relationship rel : annotNode.getRelationships(RelationTypes.HAS_TAG)) {
511                    oldHasTags.add(rel);
512                }
513                // adjust to new tags
514                if (newTags.isEmpty()) {
515                    // remove old tags
516                    if (!oldHasTags.isEmpty()) {
517                        for (Relationship rel : oldHasTags) {
518                            rel.delete();
519                            // TODO: should we delete orphan nodes too?
520                        }
521                    }
522                } else {
523                    if (!oldHasTags.isEmpty()) {
524                        // adjust old tags
525                        for (Relationship rel : oldHasTags) {
526                            String oldTag = (String) rel.getEndNode().getProperty("name", null);
527                            if (newTags.contains(oldTag)) {
528                                // tag exists
529                                newTags.remove(oldTag);
530                            } else {
531                                // tag exists no longer
532                                rel.delete();
533                                // TODO: should we delete orphan nodes too?
534                            }
535                        }
536                    }
537                    if (!newTags.isEmpty()) {
538                        // still tags to add
539                        for (String tag : newTags) {
540                            // create new tag
541                            Node tagNode = getOrCreateTagNode(new Tag(null,null,tag));
542                            getOrCreateRelation(annotNode, RelationTypes.HAS_TAG, tagNode);
543                        }
544                    }
545
546                }
547            }
548            tx.success();
549        } finally {
550            tx.finish();
551        }
552
553        // re-read and return annotation
554        Annotation storedAnnot = createAnnotationFromNode(annotNode);
555        return storedAnnot;
556    }
557
558    /**
559     * Deletes the annotation with the given id.
560     *
561     * @param id
562     */
563    public void deleteById(String id) {
564        Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle();
565        if (annotNode != null) {
566            // delete related objects
567            Transaction tx = graphDb.beginTx();
568            try {
569                for (Relationship rel : annotNode.getRelationships()) {
570                    // delete relation and the related node if it has no other
571                    // relations
572                    Node other = rel.getOtherNode(annotNode);
573                    rel.delete();
574                    if (!other.hasRelationship()) {
575                        deleteNode(other);
576                    }
577                }
578                if (!annotNode.hasRelationship()) {
579                    deleteNode(annotNode);
580                } else {
581                    logger.error("deleteById: unable to delete: Node still has relations.");
582                }
583                tx.success();
584            } finally {
585                tx.finish();
586            }
587        }
588    }
589
590    /**
591     * Returns all annotations with the given uri and/or user.
592     *
593     * @param uri
594     * @param userUri
595     * @param limit
596     * @param offset
597     * @return
598     */
599    public List<Annotation> searchByUriUser(String targetUri, String userUri, String limit, String offset) {
600        List<Annotation> annotations = new ArrayList<Annotation>();
601        if (targetUri != null) {
602            // there should be only one
603            Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri).getSingle();
604            if (target != null) {
605                Iterable<Relationship> relations = target.getRelationships(RelationTypes.ANNOTATES);
606                for (Relationship relation : relations) {
607                    Node ann = relation.getStartNode();
608                    if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
609                        Annotation annot = createAnnotationFromNode(ann);
610                        annotations.add(annot);
611                    } else {
612                        logger.error("ANNOTATES relation does not start with ANNOTATION: " + ann);
613                    }
614                }
615            }
616        }
617        if (userUri != null) {
618            // there should be only one
619            Node person = getPersonNodeByUri(userUri);
620            if (person != null) {
621                Iterable<Relationship> relations = person.getRelationships(RelationTypes.CREATED);
622                for (Relationship relation : relations) {
623                    Node ann = relation.getEndNode();
624                    if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
625                        Annotation annot = createAnnotationFromNode(ann);
626                        annotations.add(annot);
627                    } else {
628                        logger.error("CREATED relation does not end with ANNOTATION: " + ann);
629                    }
630                }
631            }
632        }
633        // TODO: if both uri and user are given we should intersect
634        return annotations;
635    }
636
637    /**
638     * Returns Relationship of type from Node start to Node end. Creates one if
639     * it doesn't exist.
640     *
641     * @param start
642     * @param type
643     * @param end
644     * @return
645     */
646    protected Relationship getOrCreateRelation(Node start, RelationshipType type, Node end) {
647        if (start.hasRelationship()) {
648            // there are relations
649            Iterable<Relationship> rels = start.getRelationships(type, Direction.OUTGOING);
650            for (Relationship rel : rels) {
651                if (rel.getEndNode().equals(end)) {
652                    // relation exists
653                    return rel;
654                }
655            }
656        }
657        // create new one
658        Relationship rel;
659        Transaction tx = graphDb.beginTx();
660        try {
661            rel = start.createRelationshipTo(end, type);
662            tx.success();
663        } finally {
664            tx.finish();
665        }
666        return rel;
667    }
668
669    protected Node getOrCreateAnnotationNode(String id) {
670        Index<Node> idx = getNodeIndex(NodeTypes.ANNOTATION);
671        IndexHits<Node> annotations = idx.get("id", id);
672        Node annotation = annotations.getSingle();
673        if (annotation == null) {
674            // does not exist yet
675            Transaction tx = graphDb.beginTx();
676            try {
677                annotation = graphDb.createNode();
678                annotation.setProperty("TYPE", NodeTypes.ANNOTATION.name());
679                annotation.setProperty("id", id);
680                idx.add(annotation, "id", id);
681                tx.success();
682            } finally {
683                tx.finish();
684            }
685        }
686        return annotation;
687    }
688
689    protected Node getOrCreateTargetNode(String uri) {
690        Index<Node> idx = getNodeIndex(NodeTypes.TARGET);
691        IndexHits<Node> targets = idx.get("uri", uri);
692        Node target = targets.getSingle();
693        if (target == null) {
694            // does not exist yet
695            Transaction tx = graphDb.beginTx();
696            try {
697                target = graphDb.createNode();
698                target.setProperty("TYPE", NodeTypes.TARGET.name());
699                target.setProperty("uri", uri);
700                idx.add(target, "uri", uri);
701                tx.success();
702            } finally {
703                tx.finish();
704            }
705        }
706        return target;
707    }
708
709    protected Node getActorNode(Actor actor) {
710        // Person/Group is identified by URI or id
711        String uri = actor.getUriString();
712        Index<Node> idx;
713        if (actor.isGroup()) {
714            idx = getNodeIndex(NodeTypes.GROUP);
715        } else {
716            idx = getNodeIndex(NodeTypes.PERSON);
717        }
718        IndexHits<Node> persons = idx.get("uri", uri);
719        Node person = persons.getSingle();
720        return person;
721    }
722   
723    protected Node getOrCreateActorNode(Actor actor) {
724        // Person/Group is identified by URI or id
725        String uri = actor.getUriString();
726        String name = actor.getName();
727        String id = actor.getId();
728        Index<Node> idx;
729        if (actor.isGroup()) {
730            idx = getNodeIndex(NodeTypes.GROUP);
731        } else {
732            idx = getNodeIndex(NodeTypes.PERSON);
733        }
734        IndexHits<Node> persons = idx.get("uri", uri);
735        Node person = persons.getSingle();
736        if (person == null) {
737            // does not exist yet
738            Transaction tx = graphDb.beginTx();
739            try {
740                person = graphDb.createNode();
741                if (actor.isGroup()) {
742                    person.setProperty("TYPE", NodeTypes.GROUP.name());
743                } else {
744                    person.setProperty("TYPE", NodeTypes.PERSON.name());
745                }
746                person.setProperty("uri", uri);
747                idx.add(person, "uri", uri);
748                if (name != null) {
749                    person.setProperty("name", name);
750                }
751                if (id != null) {
752                    person.setProperty("id", id);
753                }
754                tx.success();
755            } finally {
756                tx.finish();
757            }
758        }
759        return person;
760    }
761
762    protected Node getOrCreateTagNode(Tag inTag) {
763        Index<Node> idx = getNodeIndex(NodeTypes.TAG);
764        String tagname = inTag.getName();
765        IndexHits<Node> tags = idx.get("name", tagname);
766        Node tag = tags.getSingle();
767        if (tag == null) {
768            // does not exist yet
769            Transaction tx = graphDb.beginTx();
770            try {
771                tag = graphDb.createNode();
772                tag.setProperty("TYPE", NodeTypes.TAG.name());
773                tag.setProperty("name", tagname);
774                idx.add(tag, "name", tagname);
775               
776                tag.setProperty("id", inTag.getId());
777                tag.setProperty("uri", inTag.getUri());
778                idx.add(tag, "uri", inTag.getUri());
779               
780                tx.success();
781            } finally {
782                tx.finish();
783            }
784        }
785        return tag;
786    }
787
788    /**
789     * Create or update permissions relations for an annotation.
790     *
791     * @param annotNode
792     * @param type
793     * @param annot
794     */
795    protected void setPermissionRelation(Node annotNode, RelationTypes type, Actor actor) {
796        Node newActorNode = null;
797        if (actor != null) {
798            newActorNode = getOrCreateActorNode(actor);
799        }
800        Relationship rel = getRelation(annotNode, type, null);
801        if (rel != null) {
802            // relation exists
803            Node oldActorNode = rel.getEndNode();
804            if (!oldActorNode.equals(newActorNode)) {
805                // new admin is different
806                rel.delete();
807                if (newActorNode != null) {
808                    rel = getOrCreateRelation(annotNode, type, newActorNode);
809                }
810            }
811        } else {
812            // no relation yet
813            if (newActorNode != null) {
814                rel = getOrCreateRelation(annotNode, type, newActorNode);
815            }
816        }
817    }
818
819    /**
820     * Unindexes and deletes given Node if it has no relations.
821     *
822     * @param node
823     */
824    protected void deleteNode(Node node) {
825        Transaction tx = graphDb.beginTx();
826        try {
827            if (node.hasRelationship()) {
828                logger.error("deleteNode: unable to delete: Node still has relations.");
829            } else {
830                String ts = (String) node.getProperty("TYPE", null);
831                try {
832                    NodeTypes type = NodeTypes.valueOf(ts);
833                    getNodeIndex(type).remove(node);
834                } catch (Exception e) {
835                    logger.error("deleteNode: unable to get TYPE of node: " + node);
836                }
837                node.delete();
838            }
839            tx.success();
840        } finally {
841            tx.finish();
842        }
843    }
844
845    /**
846     * returns the (first) Relationship of RelationTypes type from Node start.
847     *
848     * @param start
849     * @param type
850     * @param direction
851     * @return
852     */
853    protected Relationship getRelation(Node start, RelationTypes type, Direction direction) {
854        Iterable<Relationship> rels;
855        if (direction == null) {
856            // ignore direction
857            rels = start.getRelationships(type);
858        } else {
859            rels = start.getRelationships(type, direction);
860        }
861        for (Relationship rel : rels) {
862            // just the first one
863            return rel;
864        }
865        return null;
866    }
867
868    /**
869     * Erzeuge eine urn aus der aktuellen Zeit in millis
870     *
871     * @return
872     */
873    private String createRessourceURI(String prefix) {
874
875        Calendar cal = Calendar.getInstance();
876
877        long time = cal.getTimeInMillis();
878
879        return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time);
880
881    }
882
883        public List<Annotation> getAnnotationsByTag(String tagUri) {
884               
885                ArrayList<Annotation> ret = new  ArrayList<Annotation>();
886                Node tag = getTagNodeByUri(tagUri);
887               
888               
889                Iterable<Relationship> rels = tag.getRelationships(Direction.INCOMING,RelationTypes.HAS_TAG);
890               
891                for (Relationship rel:rels){
892                        Node node = rel.getStartNode();
893                        ret.add(createAnnotationFromNode(node));
894                       
895                }
896                return ret;
897        }
898
899}
Note: See TracBrowser for help on using the repository browser.