Changeset 13:abe25edf2178 in AnnotationManagerN4J
- Timestamp:
- Jul 13, 2012, 3:22:05 PM (13 years ago)
- Branch:
- default
- Location:
- src/main/java/de/mpiwg/itgroup/annotations
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/main/java/de/mpiwg/itgroup/annotations/Actor.java
r10 r13 27 27 return uri; 28 28 } 29 30 /** 31 * Returns the uri (uses id if empty). 32 * 33 * @return the uri 34 */ 35 public String getUriString() { 36 if (uri == null) { 37 return getUriFromId(id, isGroup()); 38 } 39 return uri; 40 } 41 29 42 /** 30 43 * @param uri the uri to set -
src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java
r12 r13 30 30 public class AnnotationStore { 31 31 32 protected static Logger logger = Logger.getLogger(AnnotationStore.class); 33 34 protected GraphDatabaseService graphDb; 35 36 public static enum NodeTypes { 37 ANNOTATION, PERSON, TARGET 38 } 39 40 protected List<Index<Node>> nodeIndexes; 41 42 public static enum RelationTypes implements RelationshipType { 43 ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ 44 } 45 46 public static String ANNOTATION_URI_BASE = "http://entities.mpiwg-berlin.mpg.de/annotations/"; 47 48 public AnnotationStore(GraphDatabaseService graphDb) { 49 super(); 50 this.graphDb = graphDb; 51 nodeIndexes = new ArrayList<Index<Node>>(3); 52 // List.set(enum.ordinal(), val) seems not to work. 53 nodeIndexes.add(NodeTypes.ANNOTATION.ordinal(), graphDb.index().forNodes("annotations")); 54 nodeIndexes.add(NodeTypes.PERSON.ordinal(), graphDb.index().forNodes("persons")); 55 nodeIndexes.add(NodeTypes.TARGET.ordinal(), graphDb.index().forNodes("targets")); 56 } 57 58 protected Index<Node> getNodeIndex(NodeTypes type) { 59 return nodeIndexes.get(type.ordinal()); 60 } 61 62 /** 63 * Returns the Annotation with the given id. 64 * 65 * @param id 66 * @return 67 */ 68 public Annotation getAnnotationById(String id) { 69 Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle(); 70 Annotation annot = createAnnotationFromNode(annotNode); 71 return annot; 72 } 73 74 /** 75 * Returns an Annotation object from an annotation-Node. 76 * 77 * @param annotNode 78 * @return 79 */ 80 public Annotation createAnnotationFromNode(Node annotNode) { 81 Annotation annot = new Annotation(); 82 annot.setUri((String) annotNode.getProperty("id", null)); 83 annot.setBodyText((String) annotNode.getProperty("bodyText", null)); 84 annot.setBodyUri((String) annotNode.getProperty("bodyUri", null)); 85 // get annotation target from relation 86 Relationship targetRel = getRelation(annotNode, RelationTypes.ANNOTATES, null); 87 if (targetRel != null) { 88 Node target = targetRel.getEndNode(); 89 annot.setTargetBaseUri((String) target.getProperty("uri", null)); 90 } else { 91 logger.error("annotation "+annotNode+" has no target node!"); 92 } 93 annot.setTargetFragment((String) annotNode.getProperty("targetFragment", null)); 94 String ft = (String) annotNode.getProperty("fragmentType", null); 95 if (ft != null) { 96 annot.setFragmentType(FragmentTypes.valueOf(ft)); 97 } 98 // get creator from relation 99 Relationship creatorRel = getRelation(annotNode, RelationTypes.CREATED, null); 100 if (creatorRel != null) { 101 Node creatorNode = creatorRel.getStartNode(); 102 Actor creator = createActorFromNode(creatorNode); 103 annot.setCreator(creator); 104 } else { 105 logger.error("annotation "+annotNode+" has no creator node!"); 106 } 107 // get creation date 108 annot.setCreated((String) annotNode.getProperty("created", null)); 109 // get permissions 110 Relationship adminRel = getRelation(annotNode, RelationTypes.PERMITS_ADMIN, null); 111 if (adminRel != null) { 112 Node adminNode = adminRel.getEndNode(); 113 //FIXME 114 } 115 116 return annot; 117 } 118 119 /** 120 * Returns an Actor object from a node. 121 * 122 * @param actorNode 123 * @return 124 */ 125 protected Actor createActorFromNode(Node actorNode) { 126 String uri = (String) actorNode.getProperty("uri", null); 127 String name = (String) actorNode.getProperty("name", null); 128 String type = (String) actorNode.getProperty("TYPE", null); 129 Actor creator = null; 130 if (type != null && type.equals("PERSON")) { 131 creator = new Person(uri, name); 132 } else if (type != null && type.equals("GROUP")) { 133 creator = new Group(uri, name); 134 } 135 return creator; 136 } 137 138 /** 139 * Store a new annotation in the store or update an existing one. Returns 140 * the stored annotation. 141 * 142 * @param annot 143 * @return 144 */ 145 public Annotation storeAnnotation(Annotation annot) { 146 Node annotNode = null; 147 Transaction tx = graphDb.beginTx(); 148 try { 149 /* 150 * create or get the annotation 151 */ 152 String id = annot.getUri(); 153 if (id == null) { 154 id = createRessourceURI("annot:"); 155 } 156 annotNode = getOrCreateAnnotationNode(id); 157 158 /* 159 * the annotation body 160 */ 161 String bodyText = annot.getBodyText(); 162 if (bodyText != null) { 163 annotNode.setProperty("bodyText", bodyText); 164 } 165 String bodyUri = annot.getBodyUri(); 166 if (bodyUri != null) { 167 annotNode.setProperty("bodyUri", bodyUri); 168 } 169 170 /* 171 * the annotation target 172 */ 173 String targetBaseUri = annot.getTargetBaseUri(); 174 if (targetBaseUri != null) { 175 Node target = getOrCreateTargetNode(targetBaseUri); 176 getOrCreateRelation(annotNode, RelationTypes.ANNOTATES, target); 177 } 178 179 /* 180 * The fragment part of the annotation target. 181 */ 182 String targetFragment = annot.getTargetFragment(); 183 FragmentTypes fragmentType = annot.getFragmentType(); 184 if (targetFragment != null) { 185 annotNode.setProperty("targetFragment", targetFragment); 186 annotNode.setProperty("fragmentType", fragmentType.name()); 187 } 188 189 /* 190 * The creator of this annotation. 191 */ 192 Actor creator = annot.getCreator(); 193 if (creator != null) { 194 Node creatorNode = getOrCreatePersonNode(creator); 195 getOrCreateRelation(creatorNode, RelationTypes.CREATED, annotNode); 196 } 197 198 /* 199 * The creation date of this annotation. 200 */ 201 String created = annot.getCreated(); 202 if (created != null) { 203 annotNode.setProperty("created", created); 204 } 205 206 /* 207 * Permissions for this annotation. 208 */ 209 setPermissionRelation(annotNode, RelationTypes.PERMITS_ADMIN, annot.getAdminPermission()); 210 setPermissionRelation(annotNode, RelationTypes.PERMITS_DELETE, annot.getDeletePermission()); 211 setPermissionRelation(annotNode, RelationTypes.PERMITS_UPDATE, annot.getUpdatePermission()); 212 setPermissionRelation(annotNode, RelationTypes.PERMITS_READ, annot.getReadPermission()); 213 214 tx.success(); 215 } finally { 216 tx.finish(); 217 } 218 219 // re-read and return annotation 220 Annotation storedAnnot = createAnnotationFromNode(annotNode); 221 return storedAnnot; 222 } 223 224 /** 225 * Deletes the annotation with the given id. 226 * 227 * @param id 228 */ 229 public void deleteById(String id) { 230 Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle(); 231 if (annotNode != null) { 232 // delete related objects 233 Transaction tx = graphDb.beginTx(); 234 try { 235 for (Relationship rel : annotNode.getRelationships()) { 236 // delete relation and the related node if it has no other 237 // relations 238 Node other = rel.getOtherNode(annotNode); 239 rel.delete(); 240 if (!other.hasRelationship()) { 241 deleteNode(other); 242 } 243 } 244 if (!annotNode.hasRelationship()) { 245 deleteNode(annotNode); 246 } else { 247 logger.error("deleteById: unable to delete: Node still has relations."); 248 } 249 tx.success(); 250 } finally { 251 tx.finish(); 252 } 253 } 254 } 255 256 /** 257 * Returns all annotations with the given uri and/or user. 258 * 259 * @param uri 260 * @param userUri 261 * @param limit 262 * @param offset 263 * @return 264 */ 265 public List<Annotation> searchByUriUser(String targetUri, String userUri, String limit, String offset) { 266 List<Annotation> annotations = new ArrayList<Annotation>(); 267 if (targetUri != null) { 268 // there should be only one 269 Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri).getSingle(); 270 if (target != null) { 271 Iterable<Relationship> relations = target.getRelationships(RelationTypes.ANNOTATES); 272 for (Relationship relation : relations) { 273 Node ann = relation.getStartNode(); 274 if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { 275 Annotation annot = createAnnotationFromNode(ann); 276 annotations.add(annot); 277 } else { 278 logger.error("ANNOTATES relation does not start with ANNOTATION: " + ann); 279 } 280 } 281 } 282 } 283 if (userUri != null) { 284 // there should be only one 285 Node person = getNodeIndex(NodeTypes.PERSON).get("uri", userUri).getSingle(); 286 if (person != null) { 287 Iterable<Relationship> relations = person.getRelationships(RelationTypes.CREATED); 288 for (Relationship relation : relations) { 289 Node ann = relation.getEndNode(); 290 if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { 291 Annotation annot = createAnnotationFromNode(ann); 292 annotations.add(annot); 293 } else { 294 logger.error("CREATED relation does not end with ANNOTATION: " + ann); 295 } 296 } 297 } 298 } 299 return annotations; 300 } 301 302 protected Relationship getOrCreateRelation(Node start, RelationshipType type, Node end) { 303 if (start.hasRelationship()) { 304 // there are relations 305 Iterable<Relationship> rels = start.getRelationships(type, Direction.OUTGOING); 306 for (Relationship rel : rels) { 307 if (rel.getEndNode().equals(end)) { 308 // relation exists 309 return rel; 310 } 311 } 312 } 313 // create new one 314 Relationship rel; 315 Transaction tx = graphDb.beginTx(); 316 try { 317 rel = start.createRelationshipTo(end, type); 318 tx.success(); 319 } finally { 320 tx.finish(); 321 } 322 return rel; 323 } 324 325 protected Node getOrCreateAnnotationNode(String id) { 326 Index<Node> idx = getNodeIndex(NodeTypes.ANNOTATION); 327 IndexHits<Node> annotations = idx.get("id", id); 328 Node annotation = annotations.getSingle(); 329 if (annotation == null) { 330 // does not exist yet 331 Transaction tx = graphDb.beginTx(); 332 try { 333 annotation = graphDb.createNode(); 334 annotation.setProperty("TYPE", NodeTypes.ANNOTATION.name()); 335 annotation.setProperty("id", id); 336 idx.add(annotation, "id", id); 337 tx.success(); 338 } finally { 339 tx.finish(); 340 } 341 } 342 return annotation; 343 } 344 345 protected Node getOrCreateTargetNode(String uri) { 346 Index<Node> idx = getNodeIndex(NodeTypes.TARGET); 347 IndexHits<Node> targets = idx.get("uri", uri); 348 Node target = targets.getSingle(); 349 if (target == null) { 350 // does not exist yet 351 Transaction tx = graphDb.beginTx(); 352 try { 353 target = graphDb.createNode(); 354 target.setProperty("TYPE", NodeTypes.TARGET.name()); 355 target.setProperty("uri", uri); 356 idx.add(target, "uri", uri); 357 tx.success(); 358 } finally { 359 tx.finish(); 360 } 361 } 362 return target; 363 } 364 365 protected Node getOrCreatePersonNode(Actor actor) { 366 /* 367 * // Person is identified by URI Index<Node> idx = 368 * getNodeIndex(NodeTypes.PERSON); IndexHits<Node> persons = 369 * idx.get("uri", uri); Node person = persons.getSingle(); if (person == 370 * null) { // does not exist yet Transaction tx = graphDb.beginTx(); try 371 * { person = graphDb.createNode(); person.setProperty("TYPE", 372 * NodeTypes.PERSON.name()); person.setProperty("uri", uri); 373 * idx.add(person, "uri", uri); if (name != null) { 374 * person.setProperty("name", name); } tx.success(); } finally { 375 * tx.finish(); } } return person; 376 */ 377 return null; 378 } 379 380 /** 381 * Create or update permissions relations for an annotation. 382 * 383 * @param annotNode 384 * @param type 385 * @param annot 386 */ 387 protected void setPermissionRelation(Node annotNode, RelationTypes type, Actor actor) { 388 Node newActorNode = null; 389 if (actor != null) { 390 newActorNode = getOrCreatePersonNode(actor); 391 } 392 Relationship rel = getRelation(annotNode, type, null); 393 if (rel != null) { 394 // relation exists 395 Node oldActorNode = rel.getEndNode(); 396 if (!oldActorNode.equals(newActorNode)) { 397 // new admin is different 398 rel.delete(); 399 if (newActorNode != null) { 400 rel = getOrCreateRelation(annotNode, type, newActorNode); 401 } 402 } 403 } else { 404 // no relation yet 405 if (newActorNode != null) { 406 rel = getOrCreateRelation(annotNode, type, newActorNode); 407 } 408 } 409 } 410 411 /** 412 * Unindexes and deletes given Node if it has no relations. 413 * 414 * @param node 415 */ 416 protected void deleteNode(Node node) { 417 Transaction tx = graphDb.beginTx(); 418 try { 419 if (node.hasRelationship()) { 420 logger.error("deleteNode: unable to delete: Node still has relations."); 421 } else { 422 String ts = (String) node.getProperty("TYPE", null); 423 try { 424 NodeTypes type = NodeTypes.valueOf(ts); 425 getNodeIndex(type).remove(node); 426 } catch (Exception e) { 427 logger.error("deleteNode: unable to get TYPE of node: " + node); 428 } 429 node.delete(); 430 } 431 tx.success(); 432 } finally { 433 tx.finish(); 434 } 435 } 436 437 protected Relationship getRelation(Node start, RelationTypes type, Direction direction) { 438 Iterable<Relationship> rels; 439 if (direction == null) { 440 // ignore direction 441 rels = start.getRelationships(type); 442 } else { 443 rels = start.getRelationships(type, direction); 444 } 445 for (Relationship rel : rels) { 446 return rel; 447 } 448 return null; 449 } 450 451 /** 452 * Erzeuge eine urn aus der aktuellen Zeit in millis 453 * 454 * @return 455 */ 456 private String createRessourceURI(String prefix) { 457 458 Calendar cal = Calendar.getInstance(); 459 460 long time = cal.getTimeInMillis(); 461 462 return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time); 463 464 } 32 protected static Logger logger = Logger.getLogger(AnnotationStore.class); 33 34 protected GraphDatabaseService graphDb; 35 36 public static enum NodeTypes { 37 ANNOTATION, PERSON, TARGET 38 } 39 40 protected List<Index<Node>> nodeIndexes; 41 42 public static enum RelationTypes implements RelationshipType { 43 ANNOTATES, CREATED, PERMITS_ADMIN, PERMITS_DELETE, PERMITS_UPDATE, PERMITS_READ 44 } 45 46 public static String ANNOTATION_URI_BASE = "http://entities.mpiwg-berlin.mpg.de/annotations/"; 47 48 public AnnotationStore(GraphDatabaseService graphDb) { 49 super(); 50 this.graphDb = graphDb; 51 nodeIndexes = new ArrayList<Index<Node>>(3); 52 // List.set(enum.ordinal(), val) seems not to work. 53 nodeIndexes.add(NodeTypes.ANNOTATION.ordinal(), graphDb.index() 54 .forNodes("annotations")); 55 nodeIndexes.add(NodeTypes.PERSON.ordinal(), 56 graphDb.index().forNodes("persons")); 57 nodeIndexes.add(NodeTypes.TARGET.ordinal(), 58 graphDb.index().forNodes("targets")); 59 } 60 61 protected Index<Node> getNodeIndex(NodeTypes type) { 62 return nodeIndexes.get(type.ordinal()); 63 } 64 65 /** 66 * Returns the Annotation with the given id. 67 * 68 * @param id 69 * @return 70 */ 71 public Annotation getAnnotationById(String id) { 72 Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id) 73 .getSingle(); 74 Annotation annot = createAnnotationFromNode(annotNode); 75 return annot; 76 } 77 78 /** 79 * Returns an Annotation object from an annotation-Node. 80 * 81 * @param annotNode 82 * @return 83 */ 84 public Annotation createAnnotationFromNode(Node annotNode) { 85 Annotation annot = new Annotation(); 86 annot.setUri((String) annotNode.getProperty("id", null)); 87 annot.setBodyText((String) annotNode.getProperty("bodyText", null)); 88 annot.setBodyUri((String) annotNode.getProperty("bodyUri", null)); 89 // get annotation target from relation 90 Relationship targetRel = getRelation(annotNode, 91 RelationTypes.ANNOTATES, null); 92 if (targetRel != null) { 93 Node target = targetRel.getEndNode(); 94 annot.setTargetBaseUri((String) target.getProperty("uri", null)); 95 } else { 96 logger.error("annotation " + annotNode + " has no target node!"); 97 } 98 annot.setTargetFragment((String) annotNode.getProperty( 99 "targetFragment", null)); 100 String ft = (String) annotNode.getProperty("fragmentType", null); 101 if (ft != null) { 102 annot.setFragmentType(FragmentTypes.valueOf(ft)); 103 } 104 // get creator from relation 105 Relationship creatorRel = getRelation(annotNode, RelationTypes.CREATED, 106 null); 107 if (creatorRel != null) { 108 Node creatorNode = creatorRel.getStartNode(); 109 Actor creator = createActorFromNode(creatorNode); 110 annot.setCreator(creator); 111 } else { 112 logger.error("annotation " + annotNode + " has no creator node!"); 113 } 114 // get creation date 115 annot.setCreated((String) annotNode.getProperty("created", null)); 116 // get permissions 117 Relationship adminRel = getRelation(annotNode, 118 RelationTypes.PERMITS_ADMIN, null); 119 if (adminRel != null) { 120 Node adminNode = adminRel.getEndNode(); 121 Actor admin = createActorFromNode(adminNode); 122 annot.setAdminPermission(admin); 123 } 124 Relationship deleteRel = getRelation(annotNode, 125 RelationTypes.PERMITS_DELETE, null); 126 if (deleteRel != null) { 127 Node deleteNode = deleteRel.getEndNode(); 128 Actor delete = createActorFromNode(deleteNode); 129 annot.setDeletePermission(delete); 130 } 131 Relationship updateRel = getRelation(annotNode, 132 RelationTypes.PERMITS_UPDATE, null); 133 if (updateRel != null) { 134 Node updateNode = updateRel.getEndNode(); 135 Actor update = createActorFromNode(updateNode); 136 annot.setUpdatePermission(update); 137 } 138 Relationship readRel = getRelation(annotNode, 139 RelationTypes.PERMITS_READ, null); 140 if (readRel != null) { 141 Node readNode = readRel.getEndNode(); 142 Actor read = createActorFromNode(readNode); 143 annot.setReadPermission(read); 144 } 145 146 return annot; 147 } 148 149 /** 150 * Returns an Actor object from a node. 151 * 152 * @param actorNode 153 * @return 154 */ 155 protected Actor createActorFromNode(Node actorNode) { 156 String uri = (String) actorNode.getProperty("uri", null); 157 String name = (String) actorNode.getProperty("name", null); 158 String type = (String) actorNode.getProperty("TYPE", null); 159 if (type != null && type.equals("PERSON")) { 160 return new Person(uri, name); 161 } else if (type != null && type.equals("GROUP")) { 162 return new Group(uri, name); 163 } 164 return null; 165 } 166 167 /** 168 * Store a new annotation in the store or update an existing one. Returns 169 * the stored annotation. 170 * 171 * @param annot 172 * @return 173 */ 174 public Annotation storeAnnotation(Annotation annot) { 175 Node annotNode = null; 176 Transaction tx = graphDb.beginTx(); 177 try { 178 /* 179 * create or get the annotation 180 */ 181 String id = annot.getUri(); 182 if (id == null) { 183 id = createRessourceURI("annot:"); 184 } 185 annotNode = getOrCreateAnnotationNode(id); 186 187 /* 188 * the annotation body 189 */ 190 String bodyText = annot.getBodyText(); 191 if (bodyText != null) { 192 annotNode.setProperty("bodyText", bodyText); 193 } 194 String bodyUri = annot.getBodyUri(); 195 if (bodyUri != null) { 196 annotNode.setProperty("bodyUri", bodyUri); 197 } 198 199 /* 200 * the annotation target 201 */ 202 String targetBaseUri = annot.getTargetBaseUri(); 203 if (targetBaseUri != null) { 204 Node target = getOrCreateTargetNode(targetBaseUri); 205 getOrCreateRelation(annotNode, RelationTypes.ANNOTATES, target); 206 } 207 208 /* 209 * The fragment part of the annotation target. 210 */ 211 String targetFragment = annot.getTargetFragment(); 212 FragmentTypes fragmentType = annot.getFragmentType(); 213 if (targetFragment != null) { 214 annotNode.setProperty("targetFragment", targetFragment); 215 annotNode.setProperty("fragmentType", fragmentType.name()); 216 } 217 218 /* 219 * The creator of this annotation. 220 */ 221 Actor creator = annot.getCreator(); 222 if (creator != null) { 223 Node creatorNode = getOrCreatePersonNode(creator); 224 getOrCreateRelation(creatorNode, RelationTypes.CREATED, 225 annotNode); 226 } 227 228 /* 229 * The creation date of this annotation. 230 */ 231 String created = annot.getCreated(); 232 if (created != null) { 233 annotNode.setProperty("created", created); 234 } 235 236 /* 237 * Permissions for this annotation. 238 */ 239 setPermissionRelation(annotNode, RelationTypes.PERMITS_ADMIN, 240 annot.getAdminPermission()); 241 setPermissionRelation(annotNode, RelationTypes.PERMITS_DELETE, 242 annot.getDeletePermission()); 243 setPermissionRelation(annotNode, RelationTypes.PERMITS_UPDATE, 244 annot.getUpdatePermission()); 245 setPermissionRelation(annotNode, RelationTypes.PERMITS_READ, 246 annot.getReadPermission()); 247 248 tx.success(); 249 } finally { 250 tx.finish(); 251 } 252 253 // re-read and return annotation 254 Annotation storedAnnot = createAnnotationFromNode(annotNode); 255 return storedAnnot; 256 } 257 258 /** 259 * Deletes the annotation with the given id. 260 * 261 * @param id 262 */ 263 public void deleteById(String id) { 264 Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id) 265 .getSingle(); 266 if (annotNode != null) { 267 // delete related objects 268 Transaction tx = graphDb.beginTx(); 269 try { 270 for (Relationship rel : annotNode.getRelationships()) { 271 // delete relation and the related node if it has no other 272 // relations 273 Node other = rel.getOtherNode(annotNode); 274 rel.delete(); 275 if (!other.hasRelationship()) { 276 deleteNode(other); 277 } 278 } 279 if (!annotNode.hasRelationship()) { 280 deleteNode(annotNode); 281 } else { 282 logger.error("deleteById: unable to delete: Node still has relations."); 283 } 284 tx.success(); 285 } finally { 286 tx.finish(); 287 } 288 } 289 } 290 291 /** 292 * Returns all annotations with the given uri and/or user. 293 * 294 * @param uri 295 * @param userUri 296 * @param limit 297 * @param offset 298 * @return 299 */ 300 public List<Annotation> searchByUriUser(String targetUri, String userUri, 301 String limit, String offset) { 302 List<Annotation> annotations = new ArrayList<Annotation>(); 303 if (targetUri != null) { 304 // there should be only one 305 Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri) 306 .getSingle(); 307 if (target != null) { 308 Iterable<Relationship> relations = target 309 .getRelationships(RelationTypes.ANNOTATES); 310 for (Relationship relation : relations) { 311 Node ann = relation.getStartNode(); 312 if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { 313 Annotation annot = createAnnotationFromNode(ann); 314 annotations.add(annot); 315 } else { 316 logger.error("ANNOTATES relation does not start with ANNOTATION: " 317 + ann); 318 } 319 } 320 } 321 } 322 if (userUri != null) { 323 // there should be only one 324 Node person = getNodeIndex(NodeTypes.PERSON).get("uri", userUri) 325 .getSingle(); 326 if (person != null) { 327 Iterable<Relationship> relations = person 328 .getRelationships(RelationTypes.CREATED); 329 for (Relationship relation : relations) { 330 Node ann = relation.getEndNode(); 331 if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { 332 Annotation annot = createAnnotationFromNode(ann); 333 annotations.add(annot); 334 } else { 335 logger.error("CREATED relation does not end with ANNOTATION: " 336 + ann); 337 } 338 } 339 } 340 } 341 return annotations; 342 } 343 344 protected Relationship getOrCreateRelation(Node start, 345 RelationshipType type, Node end) { 346 if (start.hasRelationship()) { 347 // there are relations 348 Iterable<Relationship> rels = start.getRelationships(type, 349 Direction.OUTGOING); 350 for (Relationship rel : rels) { 351 if (rel.getEndNode().equals(end)) { 352 // relation exists 353 return rel; 354 } 355 } 356 } 357 // create new one 358 Relationship rel; 359 Transaction tx = graphDb.beginTx(); 360 try { 361 rel = start.createRelationshipTo(end, type); 362 tx.success(); 363 } finally { 364 tx.finish(); 365 } 366 return rel; 367 } 368 369 protected Node getOrCreateAnnotationNode(String id) { 370 Index<Node> idx = getNodeIndex(NodeTypes.ANNOTATION); 371 IndexHits<Node> annotations = idx.get("id", id); 372 Node annotation = annotations.getSingle(); 373 if (annotation == null) { 374 // does not exist yet 375 Transaction tx = graphDb.beginTx(); 376 try { 377 annotation = graphDb.createNode(); 378 annotation.setProperty("TYPE", NodeTypes.ANNOTATION.name()); 379 annotation.setProperty("id", id); 380 idx.add(annotation, "id", id); 381 tx.success(); 382 } finally { 383 tx.finish(); 384 } 385 } 386 return annotation; 387 } 388 389 protected Node getOrCreateTargetNode(String uri) { 390 Index<Node> idx = getNodeIndex(NodeTypes.TARGET); 391 IndexHits<Node> targets = idx.get("uri", uri); 392 Node target = targets.getSingle(); 393 if (target == null) { 394 // does not exist yet 395 Transaction tx = graphDb.beginTx(); 396 try { 397 target = graphDb.createNode(); 398 target.setProperty("TYPE", NodeTypes.TARGET.name()); 399 target.setProperty("uri", uri); 400 idx.add(target, "uri", uri); 401 tx.success(); 402 } finally { 403 tx.finish(); 404 } 405 } 406 return target; 407 } 408 409 protected Node getOrCreatePersonNode(Actor actor) { 410 // Person is identified by URI 411 String uri = actor.getUriString(); 412 String name = actor.getName(); 413 Index<Node> idx = getNodeIndex(NodeTypes.PERSON); 414 IndexHits<Node> persons = idx.get("uri", uri); 415 Node person = persons.getSingle(); 416 if (person == null) { 417 // does not exist yet 418 Transaction tx = graphDb.beginTx(); 419 try { 420 person = graphDb.createNode(); 421 person.setProperty("TYPE", NodeTypes.PERSON.name()); 422 person.setProperty("uri", uri); 423 idx.add(person, "uri", uri); 424 if (name != null) { 425 person.setProperty("name", name); 426 } 427 tx.success(); 428 } finally { 429 tx.finish(); 430 } 431 } 432 return person; 433 } 434 435 /** 436 * Create or update permissions relations for an annotation. 437 * 438 * @param annotNode 439 * @param type 440 * @param annot 441 */ 442 protected void setPermissionRelation(Node annotNode, RelationTypes type, 443 Actor actor) { 444 Node newActorNode = null; 445 if (actor != null) { 446 newActorNode = getOrCreatePersonNode(actor); 447 } 448 Relationship rel = getRelation(annotNode, type, null); 449 if (rel != null) { 450 // relation exists 451 Node oldActorNode = rel.getEndNode(); 452 if (!oldActorNode.equals(newActorNode)) { 453 // new admin is different 454 rel.delete(); 455 if (newActorNode != null) { 456 rel = getOrCreateRelation(annotNode, type, newActorNode); 457 } 458 } 459 } else { 460 // no relation yet 461 if (newActorNode != null) { 462 rel = getOrCreateRelation(annotNode, type, newActorNode); 463 } 464 } 465 } 466 467 /** 468 * Unindexes and deletes given Node if it has no relations. 469 * 470 * @param node 471 */ 472 protected void deleteNode(Node node) { 473 Transaction tx = graphDb.beginTx(); 474 try { 475 if (node.hasRelationship()) { 476 logger.error("deleteNode: unable to delete: Node still has relations."); 477 } else { 478 String ts = (String) node.getProperty("TYPE", null); 479 try { 480 NodeTypes type = NodeTypes.valueOf(ts); 481 getNodeIndex(type).remove(node); 482 } catch (Exception e) { 483 logger.error("deleteNode: unable to get TYPE of node: " 484 + node); 485 } 486 node.delete(); 487 } 488 tx.success(); 489 } finally { 490 tx.finish(); 491 } 492 } 493 494 protected Relationship getRelation(Node start, RelationTypes type, 495 Direction direction) { 496 Iterable<Relationship> rels; 497 if (direction == null) { 498 // ignore direction 499 rels = start.getRelationships(type); 500 } else { 501 rels = start.getRelationships(type, direction); 502 } 503 for (Relationship rel : rels) { 504 return rel; 505 } 506 return null; 507 } 508 509 /** 510 * Erzeuge eine urn aus der aktuellen Zeit in millis 511 * 512 * @return 513 */ 514 private String createRessourceURI(String prefix) { 515 516 Calendar cal = Calendar.getInstance(); 517 518 long time = cal.getTimeInMillis(); 519 520 return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time); 521 522 } 465 523 466 524 }
Note: See TracChangeset
for help on using the changeset viewer.