source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java @ 29:3be0ebb6d5ad

Last change on this file since 29:3be0ebb6d5ad was 29:3be0ebb6d5ad, checked in by dwinter, 12 years ago

Merge with 1cf7203009f26a8a55fc387adcb8ae6ca681520c

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