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

store seems to work now :-)
author casties
date Mon, 02 Jul 2012 22:39:46 +0200
parents
children bbf0cc5bee29
comparison
equal deleted inserted replaced
3:47b53ae385d1 4:3599b29c393f
1 /**
2 *
3 */
4 package de.mpiwg.itgroup.annotations.neo4j;
5
6 import java.util.ArrayList;
7 import java.util.Calendar;
8 import java.util.List;
9
10 import org.apache.log4j.Logger;
11 import org.neo4j.graphdb.GraphDatabaseService;
12 import org.neo4j.graphdb.Node;
13 import org.neo4j.graphdb.Relationship;
14 import org.neo4j.graphdb.RelationshipType;
15 import org.neo4j.graphdb.Transaction;
16 import org.neo4j.graphdb.index.Index;
17 import org.neo4j.graphdb.index.IndexHits;
18
19 import de.mpiwg.itgroup.annotations.Annotation;
20 import de.mpiwg.itgroup.annotations.Annotation.FragmentTypes;
21
22 /**
23 * @author casties
24 *
25 */
26 public 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 }