Changeset 14:629e15b345aa in AnnotationManagerN4J for src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java
Legend:
- Unmodified
- Added
- Removed
-
src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java
r13 r14 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() 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 } 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 Actor admin = createActorFromNode(adminNode); 114 annot.setAdminPermission(admin); 115 } 116 Relationship deleteRel = getRelation(annotNode, RelationTypes.PERMITS_DELETE, null); 117 if (deleteRel != null) { 118 Node deleteNode = deleteRel.getEndNode(); 119 Actor delete = createActorFromNode(deleteNode); 120 annot.setDeletePermission(delete); 121 } 122 Relationship updateRel = getRelation(annotNode, RelationTypes.PERMITS_UPDATE, null); 123 if (updateRel != null) { 124 Node updateNode = updateRel.getEndNode(); 125 Actor update = createActorFromNode(updateNode); 126 annot.setUpdatePermission(update); 127 } 128 Relationship readRel = getRelation(annotNode, RelationTypes.PERMITS_READ, null); 129 if (readRel != null) { 130 Node readNode = readRel.getEndNode(); 131 Actor read = createActorFromNode(readNode); 132 annot.setReadPermission(read); 133 } 134 135 return annot; 136 } 137 138 /** 139 * Returns an Actor object from a node. 140 * 141 * @param actorNode 142 * @return 143 */ 144 protected Actor createActorFromNode(Node actorNode) { 145 String uri = (String) actorNode.getProperty("uri", null); 146 String name = (String) actorNode.getProperty("name", null); 147 String type = (String) actorNode.getProperty("TYPE", null); 148 if (type != null && type.equals("PERSON")) { 149 return new Person(uri, name); 150 } else if (type != null && type.equals("GROUP")) { 151 return new Group(uri, name); 152 } 153 return null; 154 } 155 156 /** 157 * Store a new annotation in the store or update an existing one. Returns 158 * the stored annotation. 159 * 160 * @param annot 161 * @return 162 */ 163 public Annotation storeAnnotation(Annotation annot) { 164 Node annotNode = null; 165 Transaction tx = graphDb.beginTx(); 166 try { 167 /* 168 * create or get the annotation 169 */ 170 String id = annot.getUri(); 171 if (id == null) { 172 id = createRessourceURI("annot:"); 173 } 174 annotNode = getOrCreateAnnotationNode(id); 175 176 /* 177 * the annotation body 178 */ 179 String bodyText = annot.getBodyText(); 180 if (bodyText != null) { 181 annotNode.setProperty("bodyText", bodyText); 182 } 183 String bodyUri = annot.getBodyUri(); 184 if (bodyUri != null) { 185 annotNode.setProperty("bodyUri", bodyUri); 186 } 187 188 /* 189 * the annotation target 190 */ 191 String targetBaseUri = annot.getTargetBaseUri(); 192 if (targetBaseUri != null) { 193 Node target = getOrCreateTargetNode(targetBaseUri); 194 getOrCreateRelation(annotNode, RelationTypes.ANNOTATES, target); 195 } 196 197 /* 198 * The fragment part of the annotation target. 199 */ 200 String targetFragment = annot.getTargetFragment(); 201 FragmentTypes fragmentType = annot.getFragmentType(); 202 if (targetFragment != null) { 203 annotNode.setProperty("targetFragment", targetFragment); 204 annotNode.setProperty("fragmentType", fragmentType.name()); 205 } 206 207 /* 208 * The creator of this annotation. 209 */ 210 Actor creator = annot.getCreator(); 211 if (creator != null) { 212 Node creatorNode = getOrCreatePersonNode(creator); 213 getOrCreateRelation(creatorNode, RelationTypes.CREATED, annotNode); 214 } 215 216 /* 217 * The creation date of this annotation. 218 */ 219 String created = annot.getCreated(); 220 if (created != null) { 221 annotNode.setProperty("created", created); 222 } 223 224 /* 225 * Permissions for this annotation. 226 */ 227 setPermissionRelation(annotNode, RelationTypes.PERMITS_ADMIN, annot.getAdminPermission()); 228 setPermissionRelation(annotNode, RelationTypes.PERMITS_DELETE, annot.getDeletePermission()); 229 setPermissionRelation(annotNode, RelationTypes.PERMITS_UPDATE, annot.getUpdatePermission()); 230 setPermissionRelation(annotNode, RelationTypes.PERMITS_READ, annot.getReadPermission()); 231 232 tx.success(); 233 } finally { 234 tx.finish(); 235 } 236 237 // re-read and return annotation 238 Annotation storedAnnot = createAnnotationFromNode(annotNode); 239 return storedAnnot; 240 } 241 242 /** 243 * Deletes the annotation with the given id. 244 * 245 * @param id 246 */ 247 public void deleteById(String id) { 248 Node annotNode = getNodeIndex(NodeTypes.ANNOTATION).get("id", id).getSingle(); 249 if (annotNode != null) { 250 // delete related objects 251 Transaction tx = graphDb.beginTx(); 252 try { 253 for (Relationship rel : annotNode.getRelationships()) { 254 // delete relation and the related node if it has no other 255 // relations 256 Node other = rel.getOtherNode(annotNode); 257 rel.delete(); 258 if (!other.hasRelationship()) { 259 deleteNode(other); 260 } 261 } 262 if (!annotNode.hasRelationship()) { 263 deleteNode(annotNode); 264 } else { 265 logger.error("deleteById: unable to delete: Node still has relations."); 266 } 267 tx.success(); 268 } finally { 269 tx.finish(); 270 } 271 } 272 } 273 274 /** 275 * Returns all annotations with the given uri and/or user. 276 * 277 * @param uri 278 * @param userUri 279 * @param limit 280 * @param offset 281 * @return 282 */ 283 public List<Annotation> searchByUriUser(String targetUri, String userUri, String limit, String offset) { 284 List<Annotation> annotations = new ArrayList<Annotation>(); 285 if (targetUri != null) { 286 // there should be only one 287 Node target = getNodeIndex(NodeTypes.TARGET).get("uri", targetUri).getSingle(); 288 if (target != null) { 289 Iterable<Relationship> relations = target.getRelationships(RelationTypes.ANNOTATES); 290 for (Relationship relation : relations) { 291 Node ann = relation.getStartNode(); 292 if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { 293 Annotation annot = createAnnotationFromNode(ann); 294 annotations.add(annot); 295 } else { 296 logger.error("ANNOTATES relation does not start with ANNOTATION: " + ann); 297 } 298 } 299 } 300 } 301 if (userUri != null) { 302 // there should be only one 303 Node person = getNodeIndex(NodeTypes.PERSON).get("uri", userUri).getSingle(); 304 if (person != null) { 305 Iterable<Relationship> relations = person.getRelationships(RelationTypes.CREATED); 306 for (Relationship relation : relations) { 307 Node ann = relation.getEndNode(); 308 if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { 309 Annotation annot = createAnnotationFromNode(ann); 310 annotations.add(annot); 311 } else { 312 logger.error("CREATED relation does not end with ANNOTATION: " + ann); 313 } 314 } 315 } 316 } 317 return annotations; 318 } 319 320 protected Relationship getOrCreateRelation(Node start, RelationshipType type, Node end) { 321 if (start.hasRelationship()) { 322 // there are relations 323 Iterable<Relationship> rels = start.getRelationships(type, Direction.OUTGOING); 324 for (Relationship rel : rels) { 325 if (rel.getEndNode().equals(end)) { 326 // relation exists 327 return rel; 328 } 329 } 330 } 331 // create new one 332 Relationship rel; 333 Transaction tx = graphDb.beginTx(); 334 try { 335 rel = start.createRelationshipTo(end, type); 336 tx.success(); 337 } finally { 338 tx.finish(); 339 } 340 return rel; 341 } 342 343 protected Node getOrCreateAnnotationNode(String id) { 344 Index<Node> idx = getNodeIndex(NodeTypes.ANNOTATION); 345 IndexHits<Node> annotations = idx.get("id", id); 346 Node annotation = annotations.getSingle(); 347 if (annotation == null) { 348 // does not exist yet 349 Transaction tx = graphDb.beginTx(); 350 try { 351 annotation = graphDb.createNode(); 352 annotation.setProperty("TYPE", NodeTypes.ANNOTATION.name()); 353 annotation.setProperty("id", id); 354 idx.add(annotation, "id", id); 355 tx.success(); 356 } finally { 357 tx.finish(); 358 } 359 } 360 return annotation; 361 } 362 363 protected Node getOrCreateTargetNode(String uri) { 364 Index<Node> idx = getNodeIndex(NodeTypes.TARGET); 365 IndexHits<Node> targets = idx.get("uri", uri); 366 Node target = targets.getSingle(); 367 if (target == null) { 368 // does not exist yet 369 Transaction tx = graphDb.beginTx(); 370 try { 371 target = graphDb.createNode(); 372 target.setProperty("TYPE", NodeTypes.TARGET.name()); 373 target.setProperty("uri", uri); 374 idx.add(target, "uri", uri); 375 tx.success(); 376 } finally { 377 tx.finish(); 378 } 379 } 380 return target; 381 } 382 383 protected Node getOrCreatePersonNode(Actor actor) { 384 // Person is identified by URI 385 String uri = actor.getUriString(); 386 String name = actor.getName(); 387 Index<Node> idx = getNodeIndex(NodeTypes.PERSON); 388 IndexHits<Node> persons = idx.get("uri", uri); 389 Node person = persons.getSingle(); 390 if (person == null) { 391 // does not exist yet 392 Transaction tx = graphDb.beginTx(); 393 try { 394 person = graphDb.createNode(); 395 person.setProperty("TYPE", NodeTypes.PERSON.name()); 396 person.setProperty("uri", uri); 397 idx.add(person, "uri", uri); 398 if (name != null) { 399 person.setProperty("name", name); 400 } 401 tx.success(); 402 } finally { 403 tx.finish(); 404 } 405 } 406 return person; 407 } 408 409 /** 410 * Create or update permissions relations for an annotation. 411 * 412 * @param annotNode 413 * @param type 414 * @param annot 415 */ 416 protected void setPermissionRelation(Node annotNode, RelationTypes type, Actor actor) { 417 Node newActorNode = null; 418 if (actor != null) { 419 newActorNode = getOrCreatePersonNode(actor); 420 } 421 Relationship rel = getRelation(annotNode, type, null); 422 if (rel != null) { 423 // relation exists 424 Node oldActorNode = rel.getEndNode(); 425 if (!oldActorNode.equals(newActorNode)) { 426 // new admin is different 427 rel.delete(); 428 if (newActorNode != null) { 429 rel = getOrCreateRelation(annotNode, type, newActorNode); 430 } 431 } 432 } else { 433 // no relation yet 434 if (newActorNode != null) { 435 rel = getOrCreateRelation(annotNode, type, newActorNode); 436 } 437 } 438 } 439 440 /** 441 * Unindexes and deletes given Node if it has no relations. 442 * 443 * @param node 444 */ 445 protected void deleteNode(Node node) { 446 Transaction tx = graphDb.beginTx(); 447 try { 448 if (node.hasRelationship()) { 449 logger.error("deleteNode: unable to delete: Node still has relations."); 450 } else { 451 String ts = (String) node.getProperty("TYPE", null); 452 try { 453 NodeTypes type = NodeTypes.valueOf(ts); 454 getNodeIndex(type).remove(node); 455 } catch (Exception e) { 456 logger.error("deleteNode: unable to get TYPE of node: " + node); 457 } 458 node.delete(); 459 } 460 tx.success(); 461 } finally { 462 tx.finish(); 463 } 464 } 465 466 protected Relationship getRelation(Node start, RelationTypes type, Direction direction) { 467 Iterable<Relationship> rels; 468 if (direction == null) { 469 // ignore direction 470 rels = start.getRelationships(type); 471 } else { 472 rels = start.getRelationships(type, direction); 473 } 474 for (Relationship rel : rels) { 475 return rel; 476 } 477 return null; 478 } 479 480 /** 481 * Erzeuge eine urn aus der aktuellen Zeit in millis 482 * 483 * @return 484 */ 485 private String createRessourceURI(String prefix) { 486 487 Calendar cal = Calendar.getInstance(); 488 489 long time = cal.getTimeInMillis(); 490 491 return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time); 492 493 } 523 494 524 495 }
Note: See TracChangeset
for help on using the changeset viewer.