Mercurial > hg > AnnotationManagerN4J
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java Mon Jul 02 22:39:46 2012 +0200 @@ -0,0 +1,294 @@ +/** + * + */ +package de.mpiwg.itgroup.annotations.neo4j; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import org.apache.log4j.Logger; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.RelationshipType; +import org.neo4j.graphdb.Transaction; +import org.neo4j.graphdb.index.Index; +import org.neo4j.graphdb.index.IndexHits; + +import de.mpiwg.itgroup.annotations.Annotation; +import de.mpiwg.itgroup.annotations.Annotation.FragmentTypes; + +/** + * @author casties + * + */ +public class AnnotationStore { + + protected static Logger logger = Logger.getLogger(AnnotationStore.class); + + protected GraphDatabaseService graphDb; + + public static enum RelationTypes implements RelationshipType { + ANNOTATES, CREATED + } + + public static String ANNOTATION_URI_BASE = "http://entities.mpiwg-berlin.mpg.de/annotations/"; + + public AnnotationStore(GraphDatabaseService graphDb) { + super(); + this.graphDb = graphDb; + } + + public Annotation getAnnotationById(String id) { + Index<Node> idx = graphDb.index().forNodes("annotations"); + Node annotNode = idx.get("id", id).getSingle(); + Annotation annot = createAnnotation(annotNode); + return annot; + } + + /** + * Returns an Annotation object from an annotation-Node. + * + * @param annotNode + * @return + */ + public Annotation createAnnotation(Node annotNode) { + Annotation annot = new Annotation(); + annot.setUri((String) annotNode.getProperty("id", null)); + annot.setBodyText((String) annotNode.getProperty("bodyText", null)); + annot.setBodyUri((String) annotNode.getProperty("bodyUri", null)); + Iterable<Relationship> targets = annotNode.getRelationships(RelationTypes.ANNOTATES); + for (Relationship target : targets) { + annot.setTargetBaseUri((String) target.getProperty("uri", null)); + break; + } + annot.setTargetFragment((String) annotNode.getProperty("targetFragment", null)); + String ft = (String) annotNode.getProperty("fragmentType", null); + if (ft != null) { + annot.setFragmentType(FragmentTypes.valueOf(ft)); + } + Iterable<Relationship> creators = annotNode.getRelationships(RelationTypes.CREATED); + for (Relationship creator : creators) { + annot.setCreatorUri((String) creator.getProperty("uri", null)); + break; + } + annot.setCreated((String) annotNode.getProperty("created", null)); + return annot; + } + + /** + * Store a new annotation in the store or update an existing one. Returns + * the stored annotation. + * + * @param annot + * @return + */ + public Annotation storeAnnotation(Annotation annot) { + Transaction tx = graphDb.beginTx(); + Node annotNode = null; + String id = annot.getUri(); + if (id == null) { + id = createRessourceURI("annot:"); + } + annotNode = createAnnotationNode(id); + + try { + // Mutating operations go here + /* + * the annotation body + */ + String bodyText = annot.getBodyText(); + if (bodyText != null) { + annotNode.setProperty("bodyText", bodyText); + } + String bodyUri = annot.getBodyUri(); + if (bodyUri != null) { + annotNode.setProperty("bodyUri", bodyUri); + } + + /* + * the annotation target + */ + String targetBaseUri = annot.getTargetBaseUri(); + if (targetBaseUri != null) { + Node target = createTargetNode(targetBaseUri); + annotNode.createRelationshipTo(target, RelationTypes.ANNOTATES); + } + + /* + * The fragment part of the annotation target. + */ + String targetFragment = annot.getTargetFragment(); + FragmentTypes fragmentType = annot.getFragmentType(); + if (targetFragment != null) { + annotNode.setProperty("targetFragment", targetFragment); + annotNode.setProperty("fragmentType", fragmentType.name()); + } + + /* + * The URI of the creator of this annotation. + */ + String creatorUri = annot.getCreatorUri(); + if (creatorUri != null) { + Node creator = createPersonNode(creatorUri, null); + creator.createRelationshipTo(annotNode, RelationTypes.CREATED); + } + + /* + * The creation date of this annotation. + */ + String created = annot.getCreated(); + if (created != null) { + annotNode.setProperty("created", created); + } + + tx.success(); + } finally { + tx.finish(); + } + + // re-read and return annotation + Annotation storedAnnot = createAnnotation(annotNode); + return storedAnnot; + } + + /** + * Deletes the annotation with the id. + * + * @param id + */ + public void deleteById(String id) { + // TODO Auto-generated method stub + + } + + /** + * Returns all annotations with the given uri and/or user. + * + * @param uri + * @param userUri + * @param limit + * @param offset + * @return + */ + public List<Annotation> searchByUriUser(String targetUri, String userUri, String limit, String offset) { + List<Annotation> annotations = new ArrayList<Annotation>(); + if (targetUri != null) { + Index<Node> targetIdx = graphDb.index().forNodes("targets"); + // there should be only one + Node target = targetIdx.get("uri", targetUri).getSingle(); + if (target != null) { + Iterable<Relationship> relations = target.getRelationships(RelationTypes.ANNOTATES); + for (Relationship relation: relations) { + Node ann = relation.getStartNode(); + if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { + Annotation annot = createAnnotation(ann); + annotations.add(annot); + } else { + logger.error("ANNOTATES relation does not start with ANNOTATION: "+ann); + } + } + } + } + if (userUri != null) { + Index<Node> persIdx = graphDb.index().forNodes("persons"); + // there should be only one + Node person = persIdx.get("uri", userUri).getSingle(); + if (person != null) { + Iterable<Relationship> relations = person.getRelationships(RelationTypes.CREATED); + for (Relationship relation: relations) { + Node ann = relation.getEndNode(); + if (ann.getProperty("TYPE", "").equals("ANNOTATION")) { + Annotation annot = createAnnotation(ann); + annotations.add(annot); + } else { + logger.error("CREATED relation does not end with ANNOTATION: "+ann); + } + } + } + } + return annotations; + } + + protected Node createAnnotationNode(String id) { + Index<Node> idx = graphDb.index().forNodes("annotations"); + IndexHits<Node> annotations = idx.get("id", id); + Node annotation = annotations.getSingle(); + if (annotation == null) { + // does not exist yet + Transaction tx = graphDb.beginTx(); + try { + annotation = graphDb.createNode(); + annotation.setProperty("TYPE", "ANNOTATION"); + annotation.setProperty("id", id); + idx.add(annotation, "id", id); + tx.success(); + } finally { + tx.finish(); + } + } + return annotation; + } + + protected Node createTargetNode(String uri) { + Index<Node> idx = graphDb.index().forNodes("targets"); + IndexHits<Node> targets = idx.get("uri", uri); + Node target = targets.getSingle(); + if (target == null) { + // does not exist yet + Transaction tx = graphDb.beginTx(); + try { + target = graphDb.createNode(); + target.setProperty("TYPE", "TARGET"); + target.setProperty("uri", uri); + idx.add(target, "uri", uri); + tx.success(); + } finally { + tx.finish(); + } + } + return target; + } + + protected Node createPersonNode(String uri, String name) { + Index<Node> idx = graphDb.index().forNodes("persons"); + // Person is identified by URI + IndexHits<Node> persons = idx.get("uri", uri); + Node person = persons.getSingle(); + if (person == null) { + // does not exist yet + Transaction tx = graphDb.beginTx(); + try { + person = graphDb.createNode(); + person.setProperty("TYPE", "PERSON"); + person.setProperty("uri", uri); + idx.add(person, "uri", uri); + if (name != null) { + person.setProperty("name", name); + } + tx.success(); + } finally { + tx.finish(); + } + } + return person; + } + + /** + * Erzeuge eine urn aus der aktuellen Zeit in millis + * + * @return + */ + private String createRessourceURI(String prefix) { + + Calendar cal = Calendar.getInstance(); + + long time = cal.getTimeInMillis(); + + return String.format("%s%s%s", ANNOTATION_URI_BASE, prefix, time); + + } + + +}