source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java @ 24:e208a7b1a37a

Last change on this file since 24:e208a7b1a37a was 24:e208a7b1a37a, checked in by casties, 12 years ago

more work on groups ui.

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