source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java @ 4:3599b29c393f

Last change on this file since 4:3599b29c393f was 4:3599b29c393f, checked in by casties, 12 years ago

store seems to work now :-)

File size: 9.7 KB
Line 
1/**
2 *
3 */
4package de.mpiwg.itgroup.annotations.neo4j;
5
6import java.util.ArrayList;
7import java.util.Calendar;
8import java.util.List;
9
10import org.apache.log4j.Logger;
11import org.neo4j.graphdb.GraphDatabaseService;
12import org.neo4j.graphdb.Node;
13import org.neo4j.graphdb.Relationship;
14import org.neo4j.graphdb.RelationshipType;
15import org.neo4j.graphdb.Transaction;
16import org.neo4j.graphdb.index.Index;
17import org.neo4j.graphdb.index.IndexHits;
18
19import de.mpiwg.itgroup.annotations.Annotation;
20import de.mpiwg.itgroup.annotations.Annotation.FragmentTypes;
21
22/**
23 * @author casties
24 *
25 */
26public class AnnotationStore {
27
28    protected static Logger logger = Logger.getLogger(AnnotationStore.class);
29
30    protected GraphDatabaseService graphDb;
31
32    public static enum RelationTypes implements RelationshipType {
33        ANNOTATES, CREATED
34    }
35
36    public static String ANNOTATION_URI_BASE = "http://entities.mpiwg-berlin.mpg.de/annotations/";
37
38    public AnnotationStore(GraphDatabaseService graphDb) {
39        super();
40        this.graphDb = graphDb;
41    }
42
43    public Annotation getAnnotationById(String id) {
44        Index<Node> idx = graphDb.index().forNodes("annotations");
45        Node annotNode = idx.get("id", id).getSingle();
46        Annotation annot = createAnnotation(annotNode);
47        return annot;
48    }
49
50    /**
51     * Returns an Annotation object from an annotation-Node.
52     *
53     * @param annotNode
54     * @return
55     */
56    public Annotation createAnnotation(Node annotNode) {
57        Annotation annot = new Annotation();
58        annot.setUri((String) annotNode.getProperty("id", null));
59        annot.setBodyText((String) annotNode.getProperty("bodyText", null));
60        annot.setBodyUri((String) annotNode.getProperty("bodyUri", null));
61        Iterable<Relationship> targets = annotNode.getRelationships(RelationTypes.ANNOTATES);
62        for (Relationship target : targets) {
63            annot.setTargetBaseUri((String) target.getProperty("uri", null));
64            break;
65        }
66        annot.setTargetFragment((String) annotNode.getProperty("targetFragment", null));
67        String ft = (String) annotNode.getProperty("fragmentType", null);
68        if (ft != null) {
69            annot.setFragmentType(FragmentTypes.valueOf(ft));
70        }
71        Iterable<Relationship> creators = annotNode.getRelationships(RelationTypes.CREATED);
72        for (Relationship creator : creators) {
73            annot.setCreatorUri((String) creator.getProperty("uri", null));
74            break;
75        }
76        annot.setCreated((String) annotNode.getProperty("created", null));
77        return annot;
78    }
79
80    /**
81     * Store a new annotation in the store or update an existing one. Returns
82     * the stored annotation.
83     *
84     * @param annot
85     * @return
86     */
87    public Annotation storeAnnotation(Annotation annot) {
88        Transaction tx = graphDb.beginTx();
89        Node annotNode = null;
90        String id = annot.getUri();
91        if (id == null) {
92            id = createRessourceURI("annot:");
93        }
94        annotNode = createAnnotationNode(id);
95
96        try {
97            // Mutating operations go here
98            /*
99             * the annotation body
100             */
101            String bodyText = annot.getBodyText();
102            if (bodyText != null) {
103                annotNode.setProperty("bodyText", bodyText);
104            }
105            String bodyUri = annot.getBodyUri();
106            if (bodyUri != null) {
107                annotNode.setProperty("bodyUri", bodyUri);
108            }
109
110            /*
111             * the annotation target
112             */
113            String targetBaseUri = annot.getTargetBaseUri();
114            if (targetBaseUri != null) {
115                Node target = createTargetNode(targetBaseUri);
116                annotNode.createRelationshipTo(target, RelationTypes.ANNOTATES);
117            }
118
119            /*
120             * The fragment part of the annotation target.
121             */
122            String targetFragment = annot.getTargetFragment();
123            FragmentTypes fragmentType = annot.getFragmentType();
124            if (targetFragment != null) {
125                annotNode.setProperty("targetFragment", targetFragment);
126                annotNode.setProperty("fragmentType", fragmentType.name());
127            }
128
129            /*
130             * The URI of the creator of this annotation.
131             */
132            String creatorUri = annot.getCreatorUri();
133            if (creatorUri != null) {
134                Node creator = createPersonNode(creatorUri, null);
135                creator.createRelationshipTo(annotNode, RelationTypes.CREATED);
136            }
137
138            /*
139             * The creation date of this annotation.
140             */
141            String created = annot.getCreated();
142            if (created != null) {
143                annotNode.setProperty("created", created);
144            }
145
146            tx.success();
147        } finally {
148            tx.finish();
149        }
150
151        // re-read and return annotation
152        Annotation storedAnnot = createAnnotation(annotNode);
153        return storedAnnot;
154    }
155
156    /**
157     * Deletes the annotation with the id.
158     *
159     * @param id
160     */
161    public void deleteById(String id) {
162        // TODO Auto-generated method stub
163
164    }
165
166    /**
167     * Returns all annotations with the given uri and/or user.
168     *
169     * @param uri
170     * @param userUri
171     * @param limit
172     * @param offset
173     * @return
174     */
175    public List<Annotation> searchByUriUser(String targetUri, String userUri, String limit, String offset) {
176        List<Annotation> annotations = new ArrayList<Annotation>();
177        if (targetUri != null) {
178            Index<Node> targetIdx = graphDb.index().forNodes("targets");
179            // there should be only one
180            Node target = targetIdx.get("uri", targetUri).getSingle();
181            if (target != null) {
182                Iterable<Relationship> relations = target.getRelationships(RelationTypes.ANNOTATES);
183                for (Relationship relation: relations) {
184                    Node ann = relation.getStartNode();
185                    if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
186                        Annotation annot = createAnnotation(ann);
187                        annotations.add(annot);
188                    } else {
189                        logger.error("ANNOTATES relation does not start with ANNOTATION: "+ann);
190                    }
191                }
192            }
193        }
194        if (userUri != null) {
195            Index<Node> persIdx = graphDb.index().forNodes("persons");
196            // there should be only one
197            Node person = persIdx.get("uri", userUri).getSingle();
198            if (person != null) {
199                Iterable<Relationship> relations = person.getRelationships(RelationTypes.CREATED);
200                for (Relationship relation: relations) {
201                    Node ann = relation.getEndNode();
202                    if (ann.getProperty("TYPE", "").equals("ANNOTATION")) {
203                        Annotation annot = createAnnotation(ann);
204                        annotations.add(annot);
205                    } else {
206                        logger.error("CREATED relation does not end with ANNOTATION: "+ann);
207                    }
208                }
209            }
210        }
211        return annotations;
212    }
213
214    protected Node createAnnotationNode(String id) {
215        Index<Node> idx = graphDb.index().forNodes("annotations");
216        IndexHits<Node> annotations = idx.get("id", id);
217        Node annotation = annotations.getSingle();
218        if (annotation == null) {
219            // does not exist yet
220            Transaction tx = graphDb.beginTx();
221            try {
222                annotation = graphDb.createNode();
223                annotation.setProperty("TYPE", "ANNOTATION");
224                annotation.setProperty("id", id);
225                idx.add(annotation, "id", id);
226                tx.success();
227            } finally {
228                tx.finish();
229            }
230        }
231        return annotation;
232    }
233
234    protected Node createTargetNode(String uri) {
235        Index<Node> idx = graphDb.index().forNodes("targets");
236        IndexHits<Node> targets = idx.get("uri", uri);
237        Node target = targets.getSingle();
238        if (target == null) {
239            // does not exist yet
240            Transaction tx = graphDb.beginTx();
241            try {
242                target = graphDb.createNode();
243                target.setProperty("TYPE", "TARGET");
244                target.setProperty("uri", uri);
245                idx.add(target, "uri", uri);
246                tx.success();
247            } finally {
248                tx.finish();
249            }
250        }
251        return target;
252    }
253
254    protected Node createPersonNode(String uri, String name) {
255        Index<Node> idx = graphDb.index().forNodes("persons");
256        // Person is identified by URI
257        IndexHits<Node> persons = idx.get("uri", uri);
258        Node person = persons.getSingle();
259        if (person == null) {
260            // does not exist yet
261            Transaction tx = graphDb.beginTx();
262            try {
263                person = graphDb.createNode();
264                person.setProperty("TYPE", "PERSON");
265                person.setProperty("uri", uri);
266                idx.add(person, "uri", uri);
267                if (name != null) {
268                    person.setProperty("name", name);
269                }
270                tx.success();
271            } finally {
272                tx.finish();
273            }
274        }
275        return person;
276    }
277
278    /**
279     * Erzeuge eine urn aus der aktuellen Zeit in millis
280     *
281     * @return
282     */
283    private String createRessourceURI(String prefix) {
284
285        Calendar cal = Calendar.getInstance();
286
287        long time = cal.getTimeInMillis();
288
289        return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time);
290
291    }
292
293
294}
Note: See TracBrowser for help on using the repository browser.