# HG changeset patch
# User casties
# Date 1341343397 -7200
# Node ID bbf0cc5bee294ae880b76c3464a28826d992a52a
# Parent 3599b29c393f1915e53f674f6ff4907d7b39c629
version 0.2 really works now
diff -r 3599b29c393f -r bbf0cc5bee29 pom.xml
--- a/pom.xml Mon Jul 02 22:39:46 2012 +0200
+++ b/pom.xml Tue Jul 03 21:23:17 2012 +0200
@@ -3,7 +3,7 @@
4.0.0
de.mpiwg.itgroup.annotations
AnnotationManagerN4J
- 0.0.1-SNAPSHOT
+ 0.2.0-SNAPSHOT
UTF-8
1.7.1
@@ -21,11 +21,11 @@
false
-
- maven-restlet
- Public online Restlet repository
- http://maven.restlet.org
-
+
+ maven-restlet
+ Public online Restlet repository
+ http://maven.restlet.org
+
@@ -70,18 +70,19 @@
-
- log4j
- log4j
- 1.2.14
-
-
- commons-codec
- commons-codec
- 1.4
-
+
+ log4j
+ log4j
+ 1.2.14
+
+
+ commons-codec
+ commons-codec
+ 1.4
+
+ AnnotationManager
diff -r 3599b29c393f -r bbf0cc5bee29 src/main/java/de/mpiwg/itgroup/annotations/Annotation.java
--- a/src/main/java/de/mpiwg/itgroup/annotations/Annotation.java Mon Jul 02 22:39:46 2012 +0200
+++ b/src/main/java/de/mpiwg/itgroup/annotations/Annotation.java Tue Jul 03 21:23:17 2012 +0200
@@ -52,6 +52,11 @@
protected String creatorUri;
/**
+ * The full name of the creator of this annotation.
+ */
+ protected String creatorName;
+
+ /**
* The creation date of this annotation.
*/
protected String created;
@@ -155,6 +160,20 @@
}
/**
+ * @return the creatorName
+ */
+ public String getCreatorName() {
+ return creatorName;
+ }
+
+ /**
+ * @param creatorName the creatorName to set
+ */
+ public void setCreatorName(String creatorName) {
+ this.creatorName = creatorName;
+ }
+
+ /**
* @return the created
*/
public String getCreated() {
diff -r 3599b29c393f -r bbf0cc5bee29 src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java
--- a/src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java Mon Jul 02 22:39:46 2012 +0200
+++ b/src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java Tue Jul 03 21:23:17 2012 +0200
@@ -8,6 +8,7 @@
import java.util.List;
import org.apache.log4j.Logger;
+import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
@@ -58,9 +59,12 @@
annot.setUri((String) annotNode.getProperty("id", null));
annot.setBodyText((String) annotNode.getProperty("bodyText", null));
annot.setBodyUri((String) annotNode.getProperty("bodyUri", null));
- Iterable targets = annotNode.getRelationships(RelationTypes.ANNOTATES);
- for (Relationship target : targets) {
+ // get annotation target from relation
+ Iterable targetRels = annotNode.getRelationships(RelationTypes.ANNOTATES);
+ for (Relationship targetRel : targetRels) {
+ Node target = targetRel.getEndNode();
annot.setTargetBaseUri((String) target.getProperty("uri", null));
+ // just the first one
break;
}
annot.setTargetFragment((String) annotNode.getProperty("targetFragment", null));
@@ -68,9 +72,13 @@
if (ft != null) {
annot.setFragmentType(FragmentTypes.valueOf(ft));
}
- Iterable creators = annotNode.getRelationships(RelationTypes.CREATED);
- for (Relationship creator : creators) {
+ // get creator form relation
+ Iterable creatorRels = annotNode.getRelationships(RelationTypes.CREATED);
+ for (Relationship creatorRel : creatorRels) {
+ Node creator = creatorRel.getStartNode();
annot.setCreatorUri((String) creator.getProperty("uri", null));
+ annot.setCreatorName((String) creator.getProperty("name", null));
+ // just the first one
break;
}
annot.setCreated((String) annotNode.getProperty("created", null));
@@ -85,16 +93,18 @@
* @return
*/
public Annotation storeAnnotation(Annotation annot) {
+ Node annotNode = null;
Transaction tx = graphDb.beginTx();
- Node annotNode = null;
- String id = annot.getUri();
- if (id == null) {
- id = createRessourceURI("annot:");
- }
- annotNode = createAnnotationNode(id);
+ try {
+ /*
+ * create or get the annotation
+ */
+ String id = annot.getUri();
+ if (id == null) {
+ id = createRessourceURI("annot:");
+ }
+ annotNode = getOrCreateAnnotationNode(id);
- try {
- // Mutating operations go here
/*
* the annotation body
*/
@@ -112,8 +122,8 @@
*/
String targetBaseUri = annot.getTargetBaseUri();
if (targetBaseUri != null) {
- Node target = createTargetNode(targetBaseUri);
- annotNode.createRelationshipTo(target, RelationTypes.ANNOTATES);
+ Node target = getOrCreateTargetNode(targetBaseUri);
+ getOrCreateRelation(annotNode, RelationTypes.ANNOTATES, target);
}
/*
@@ -127,12 +137,17 @@
}
/*
+ * The name of the creator of this annotation.
+ */
+ String creatorName = annot.getCreatorName();
+
+ /*
* 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);
+ Node creator = getOrCreatePersonNode(creatorUri, creatorName);
+ getOrCreateRelation(creator, RelationTypes.CREATED, annotNode);
}
/*
@@ -180,13 +195,13 @@
Node target = targetIdx.get("uri", targetUri).getSingle();
if (target != null) {
Iterable relations = target.getRelationships(RelationTypes.ANNOTATES);
- for (Relationship relation: relations) {
+ 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);
+ logger.error("ANNOTATES relation does not start with ANNOTATION: " + ann);
}
}
}
@@ -197,13 +212,13 @@
Node person = persIdx.get("uri", userUri).getSingle();
if (person != null) {
Iterable relations = person.getRelationships(RelationTypes.CREATED);
- for (Relationship relation: relations) {
+ 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);
+ logger.error("CREATED relation does not end with ANNOTATION: " + ann);
}
}
}
@@ -211,7 +226,30 @@
return annotations;
}
- protected Node createAnnotationNode(String id) {
+ protected Relationship getOrCreateRelation(Node start, RelationshipType type, Node end) {
+ if (start.hasRelationship()) {
+ // there are relations
+ Iterable rels = start.getRelationships(type, Direction.OUTGOING);
+ for (Relationship rel : rels) {
+ if (rel.getEndNode().equals(end)) {
+ // relation exists
+ return rel;
+ }
+ }
+ }
+ // create new one
+ Relationship rel;
+ Transaction tx = graphDb.beginTx();
+ try {
+ rel = start.createRelationshipTo(end, type);
+ tx.success();
+ } finally {
+ tx.finish();
+ }
+ return rel;
+ }
+
+ protected Node getOrCreateAnnotationNode(String id) {
Index idx = graphDb.index().forNodes("annotations");
IndexHits annotations = idx.get("id", id);
Node annotation = annotations.getSingle();
@@ -231,7 +269,7 @@
return annotation;
}
- protected Node createTargetNode(String uri) {
+ protected Node getOrCreateTargetNode(String uri) {
Index idx = graphDb.index().forNodes("targets");
IndexHits targets = idx.get("uri", uri);
Node target = targets.getSingle();
@@ -251,7 +289,7 @@
return target;
}
- protected Node createPersonNode(String uri, String name) {
+ protected Node getOrCreatePersonNode(String uri, String name) {
Index idx = graphDb.index().forNodes("persons");
// Person is identified by URI
IndexHits persons = idx.get("uri", uri);
@@ -290,5 +328,4 @@
}
-
}
diff -r 3599b29c393f -r bbf0cc5bee29 src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java
--- a/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java Mon Jul 02 22:39:46 2012 +0200
+++ b/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java Tue Jul 03 21:23:17 2012 +0200
@@ -8,7 +8,9 @@
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.SignatureException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -177,6 +179,7 @@
* @return
*/
public JSONObject createAnnotatorJson(Annotation annot) {
+ // return user as a JSON object (otherwise just as string)
boolean makeUserObject = true;
JSONObject jo = new JSONObject();
try {
@@ -197,8 +200,11 @@
// save as id
userObject.put("id", userId);
// get full name
- RestServer restServer = (RestServer) getApplication();
- String userName = restServer.getUserNameFromLdap(userId);
+ String userName = annot.getCreatorName();
+ if (userName == null) {
+ RestServer restServer = (RestServer) getApplication();
+ userName = restServer.getFullNameFromLdap(userId);
+ }
userObject.put("name", userName);
// save user object
jo.put("user", userObject);
@@ -240,7 +246,8 @@
try {
for (String xpointer : xpointers) {
- String decoded = URLDecoder.decode(xpointer, "utf-8");
+ //String decoded = URLDecoder.decode(xpointer, "utf-8");
+ String decoded = xpointer;
Matcher m = rg.matcher(decoded);
if (m.find()) {
@@ -265,11 +272,7 @@
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
}
-
return ja;
}
@@ -281,7 +284,8 @@
try {
for (String xpointer : xpointers) {
- String decoded = URLDecoder.decode(xpointer, "utf-8");
+ //String decoded = URLDecoder.decode(xpointer, "utf-8");
+ String decoded = xpointer;
Matcher m = rg.matcher(decoded);
if (m.find()) {
@@ -299,15 +303,11 @@
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
}
-
return ja;
}
- protected String parseArea(JSONObject area) throws JSONException, UnsupportedEncodingException {
+ protected String parseArea(JSONObject area) throws JSONException {
String x = area.getString("x");
String y = area.getString("y");
String width = "0";
@@ -316,24 +316,24 @@
width = area.getString("width");
height = area.getString("height");
}
- String fragment = URLEncoder.encode(String.format("xywh=fraction:%s,%s,%s,%s", x, y, width, height), "utf-8");
+ String fragment = String.format("xywh=fraction:%s,%s,%s,%s", x, y, width, height);
return fragment;
}
- protected String parseRange(JSONObject range) throws JSONException, UnsupportedEncodingException {
+ protected String parseRange(JSONObject range) throws JSONException {
String start = range.getString("start");
String end = range.getString("end");
String startOffset = range.getString("startOffset");
String endOffset = range.getString("endOffset");
- String fragment = URLEncoder.encode(String.format(
+ String fragment = String.format(
"xpointer(start-point(string-range(\"%s\",%s,1))/range-to(end-point(string-range(\"%s\",%s,1))))", start,
- startOffset, end, endOffset), "utf-8");
+ startOffset, end, endOffset);
return fragment;
}
/**
- * creates an Annotation object with data from JSON.
+ * Creates an Annotation object with data from JSON.
*
* uses the specification from the annotator project: {@link https
* ://github.com/okfn/annotator/wiki/Annotation-format}
@@ -351,9 +351,25 @@
return updateAnnotation(new Annotation(), jo, entity);
}
+ /**
+ * Updates an Annotation object with data from JSON.
+ *
+ * uses the specification from the annotator project: {@link https
+ * ://github.com/okfn/annotator/wiki/Annotation-format}
+ *
+ * The username will be transformed to an URI if not given already as URI,
+ * if not it will set to the MPIWG namespace defined in
+ * de.mpiwg.itgroup.annotationManager.Constants.NS
+ *
+ * @param annot
+ * @param jo
+ * @return
+ * @throws JSONException
+ * @throws UnsupportedEncodingException
+ */
public Annotation updateAnnotation(Annotation annot, JSONObject jo, Representation entity) throws JSONException,
UnsupportedEncodingException {
- // annotated uri
+ // target uri
if (jo.has("uri")) {
annot.setTargetBaseUri(jo.getString("uri"));
}
@@ -396,9 +412,13 @@
if (username == null) {
username = authUser;
}
- // username should be a URI, if not it will set to the MPIWG namespace
- // defined in
- // de.mpiwg.itgroup.annotationManager.Constants.NS
+ // try to get full name
+ if (username != null) {
+ RestServer restServer = (RestServer) getApplication();
+ String fullName = restServer.getFullNameFromLdap(username);
+ annot.setCreatorName(fullName);
+ }
+ // userUri should be a URI, if not it will set to the MPIWG namespace
if (userUri == null) {
if (username.startsWith("http")) {
userUri = username;
@@ -407,6 +427,16 @@
}
}
// TODO: should we overwrite the creator?
+ if (annot.getCreatorUri() == null) {
+ annot.setCreatorUri(userUri);
+ }
+
+ if (annot.getCreated() == null) {
+ // set creation date
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ String ct = format.format(Calendar.getInstance().getTime());
+ annot.setCreated(ct);
+ }
// create xpointer from the first range/area
if (jo.has("ranges")) {
diff -r 3599b29c393f -r bbf0cc5bee29 src/main/java/de/mpiwg/itgroup/annotations/restlet/RestServer.java
--- a/src/main/java/de/mpiwg/itgroup/annotations/restlet/RestServer.java Mon Jul 02 22:39:46 2012 +0200
+++ b/src/main/java/de/mpiwg/itgroup/annotations/restlet/RestServer.java Tue Jul 03 21:23:17 2012 +0200
@@ -40,9 +40,13 @@
private Properties consumerKeys;
public String CONSUMER_KEYS_PATH = "WEB-INF/consumerkeys.property";
+ private Properties serverConfig;
+ public String CONFIG_PROPS_PATH = "WEB-INF/serverconfig.property";
+
private GraphDatabaseService graphDb;
public static final String GRAPHDB_KEY = "annotationmanager.graphdb";
- public String DB_PATH = "WEB-INF/neo4j-annotation-db";
+ public static final String GRAPHDB_PATH_KEY = "annotationmanager.graphdb.path";
+ public String graphdbPath = "WEB-INF/neo4j-annotation-db";
private WrappingNeoServerBootstrapper srv;
public static final String GRAPHDBSRV_KEY = "annotationmanager.graphdb.srv";
@@ -63,13 +67,33 @@
ServletContext sc = (ServletContext) getContext().getServerDispatcher().getContext().getAttributes()
.get("org.restlet.ext.servlet.ServletContext");
if (sc != null) {
+ /*
+ * read config from webapp
+ */
+ serverConfig = new Properties();
+ InputStream ps1 = getResourceAsStream(sc, CONFIG_PROPS_PATH);
+ if (ps1 != null) {
+ logger.debug("loading config from " + CONFIG_PROPS_PATH);
+ try {
+ serverConfig.load(ps1);
+ /*
+ * read serverconfig options
+ */
+ graphdbPath = serverConfig.getProperty(GRAPHDB_PATH_KEY, graphdbPath);
+ } catch (IOException e) {
+ logger.warn("Error loading server config: ", e);
+ }
+ logger.debug("config: " + serverConfig);
+ } else {
+ logger.error("Unable to get resource " + CONFIG_PROPS_PATH);
+ }
// look for database service in context
graphDb = (GraphDatabaseService) sc.getAttribute(GRAPHDB_KEY);
if (graphDb == null) {
/*
* open database
*/
- String dbFn = getResourcePath(sc, DB_PATH);
+ String dbFn = getResourcePath(sc, graphdbPath);
if (dbFn != null) {
logger.debug("opening DB " + dbFn);
graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(dbFn);
@@ -86,18 +110,18 @@
sc.setAttribute(GRAPHDBSRV_KEY, srv);
srv.start();
} else {
- logger.error("Unable to get resource " + DB_PATH);
+ logger.error("Unable to get resource " + dbFn);
}
}
/*
* read consumerKeys from webapp
*/
consumerKeys = new Properties();
- InputStream ps = getResourceAsStream(sc, CONSUMER_KEYS_PATH);
- if (ps != null) {
+ InputStream ps2 = getResourceAsStream(sc, CONSUMER_KEYS_PATH);
+ if (ps2 != null) {
logger.debug("loading consumer keys from " + CONSUMER_KEYS_PATH);
try {
- consumerKeys.load(ps);
+ consumerKeys.load(ps2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -154,7 +178,7 @@
* @param creator
* @return
*/
- public String getUserNameFromLdap(String creator) {
+ public String getFullNameFromLdap(String creator) {
String retString = creator; // falls nichts gefunden wird einfach den
// creator zurueckgeben
Hashtable env = new Hashtable();
@@ -162,7 +186,7 @@
env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, sp);
// TODO: should go into config file
- String ldapUrl = "ldap://ldapreplik.mpiwg-berlin.mpg.de/dc=mpiwg-berlin,dc=mpg,dc=de";
+ String ldapUrl = "ldap://ldap.mpiwg-berlin.mpg.de/dc=mpiwg-berlin,dc=mpg,dc=de";
env.put(javax.naming.Context.PROVIDER_URL, ldapUrl);
DirContext dctx;
@@ -174,7 +198,7 @@
return retString;
}
- String base = "ou=People";
+ String base = "ou=people";
SearchControls sc = new SearchControls();
String[] attributeFilter = { "cn", "mail" };