Mercurial > hg > AnnotationManager
changeset 0:77530be3c747
intial
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.classpath Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/JVM 1.6.0 (MacOS X Default)"> + <attributes> + <attribute name="owner.project.facets" value="java"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v6.0"> + <attributes> + <attribute name="owner.project.facets" value="jst.web"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/> + <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/> + <classpathentry combineaccessrules="false" kind="src" path="/NamedIdentityManager"/> + <classpathentry kind="lib" path="libs/log4j-1.2.15.jar"> + <attributes> + <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> + </attributes> + </classpathentry> + <classpathentry kind="lib" path="libs/org.restlet.ext.json.jar"> + <attributes> + <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> + </attributes> + </classpathentry> + <classpathentry kind="lib" path="libs/org.json.jar"> + <attributes> + <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> + </attributes> + </classpathentry> + <classpathentry kind="lib" path="libs/org.restlet.ext.jaas.jar"/> + <classpathentry kind="output" path="build/classes"/> +</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.project Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>AnnotationManager</name> + <comment></comment> + <projects> + <project>NamedIdentityManager</project> + <project>protege</project> + <project>protege-core</project> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.jsdt.core.javascriptValidator</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.wst.validation.validationbuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jem.workbench.JavaEMFNature</nature> + <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.jsdt.core.jsNature</nature> + </natures> +</projectDescription>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/.jsdtscope Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="WebContent"/> + <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject"> + <attributes> + <attribute name="hide" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/> + <classpathentry kind="output" path=""/> +</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.jdt.core.prefs Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,8 @@ +#Fri Oct 28 19:18:03 CEST 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.wst.common.component Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project-modules id="moduleCoreId" project-version="1.5.0"> + <wb-module deploy-name="AnnotationManager"> + <wb-resource deploy-path="/" source-path="/WebContent"/> + <wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/> + <dependent-module archiveName="NamedIdentityManager.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/NamedIdentityManager/NamedIdentityManager"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="org.restlet.ext.jaas.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/AnnotationManager/libs/org.restlet.ext.jaas.jar"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="openrdf-sesame-2.3.2-onejar.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/NamedIdentityManager/libs/openrdf-sesame-2.3.2-onejar.jar"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="protege.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/protege/protege"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="protege-core.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/protege-core/protege-core"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="virtjdbc3.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/NamedIdentityManager/libs/virtjdbc3.jar"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="virtjdbc4.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/NamedIdentityManager/libs/virtjdbc4.jar"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="virt_sesame2.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/NamedIdentityManager/libs/virt_sesame2.jar"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="virtjdbc3ssl.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/NamedIdentityManager/libs/virtjdbc3ssl.jar"> + <dependency-type>uses</dependency-type> + </dependent-module> + <dependent-module archiveName="virtjdbc4ssl.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/NamedIdentityManager/libs/virtjdbc4ssl.jar"> + <dependency-type>uses</dependency-type> + </dependent-module> + <property name="context-root" value="AnnotationManager"/> + <property name="java-output-path" value="/AnnotationManager/build/classes"/> + </wb-module> +</project-modules>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <runtime name="Apache Tomcat v6.0"/> + <fixed facet="jst.web"/> + <fixed facet="wst.jsdt.web"/> + <fixed facet="java"/> + <installed facet="java" version="1.6"/> + <installed facet="jst.web" version="2.5"/> + <installed facet="wst.jsdt.web" version="1.0"/> +</faceted-project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,1 @@ +Window \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebContent/META-INF/MANIFEST.MF Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebContent/WEB-INF/web.xml.template Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<web-app id="WebApp_ID" version="2.4" +xmlns="http://java.sun.com/xml/ns/j2ee" +xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee +http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> +<display-name>RESTfulJavaWebServices-Restlet</display-name> +<!-- Application classname --> +<context-param> +<param-name>org.restlet.application</param-name> +<param-value>de.mpiwg.itgroup.annotationManager.restlet.RestServer</param-value> +</context-param> + + +<context-param> +<param-name>de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUser</param-name> +<param-value>USERNAME</param-value> +</context-param> +<context-param> +<param-name>de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUserPassword</param-name> +<param-value>PASSWORD</param-value> +</context-param> +<!-- Restletadapter --> +<servlet> +<servlet-name>RestletServlet</servlet-name> +<servlet-class> +org.restlet.ext.servlet.ServerServlet +</servlet-class> +</servlet> + +<!-- Catchallrequests --> +<servlet-mapping> +<servlet-name>RestletServlet</servlet-name> +<url-pattern>/annotator/*</url-pattern> +</servlet-mapping> +</web-app> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebContent/index.html Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,12 @@ +<html> +<body> +<form method="post" action="annotator/annotations"> +<div>User: <input type="text" name="username"/></div> +<div>Password: <input type="password" name="password"/></div> +<div>Pointer (what to be annotated): <input type="text" name="xpointer" size="100"/></div> +<div>URL (of the annotation,optional ): <input type="text" name="url" size="100"/></div> +<div>Text:<textarea name="text" cols="100" rows="10"></textarea></div> +<div><input type="submit" name="submit"/></div> +</form> +</body> +</html> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/howToTest.txt Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,17 @@ +Test POST: + +curl -i -X POST -d "username=james&xpointer=xx" http://127.0.01:8280/AnnotationManager/annotations + +curl -i -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"username":"testname","xpointer":"xx","text":"mytext"}' http://127.0.0.1:8280/AnnotationManager/annotator/annotations + +curl -i -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"username":"testname","xpointer":"xx","text":"mytext"}' http://euler.mpiwg-berlin.mpg.de:58080/AnnotationManager/annotator/annotations + + +curl -i -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d ' {"id": "39fc339cf058bd22176771b3e3187329","created": "2011-05-24T18:52:08.036814","uri": "http://some.uri","text": "A note I wrote", "quote": "The lady said this.","ranges": [{"start": "/p[69]/font/font", "end": "/p[70]/font/font", "startOffset": "0", "endOffset": "120"}], "annotator_schema_version": "v1.0"}' http://127.0.0.1:8280/AnnotationManager/annotator/annotations + + +Test: get: + +curl -i -H "Accept: application/json" -X GET http://127.0.0.1:8280/AnnotationManager/annotator/annotations?uri=http://www.mpiwg-berlin.mpg.de + +curl -i -H "Accept: application/json" -X GET http://127.0.0.1:8280/AnnotationManager/annotator/annotations?uri=http://some.uri
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/jaas_config_example Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,9 @@ +File Edit Options Buffers Tools Help +BasicJaasAuthenticationApplication { + com.sun.security.auth.module.LdapLoginModule REQUIRED + userProvider="ldap://mpiwgldap.mpiwg-berlin.mpg.de/ou=people,dc=mpiwg-berlin,dc=mpg,dc=de" + userFilter="(&(uid={USERNAME})(objectClass=inetOrgPerson))" + debug=true + useSSL=false +; +}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/testBook.jpage Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,1 @@ +Syntax error on token "",0,1))/range-to(end-point(string-range("", delete this token Pattern rg = Pattern.compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)"); Matcher m = rg.matcher("http://some.uri#xpointer(start-point(string-range(\"/p[69]/font/font\",0,1))/range-to(end-point(string-range(\"/p[70]/font/font\",120,1))))"); m.find(); System.out.println(m.group(4)); (No explicit return value) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/Constants/NS.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,9 @@ +package de.mpiwg.itgroup.annotationManager.Constants; + +public class NS { + public static String ANNOTATION_TYPE="http://www.w3.org/2000/10/annotationType#"; + public static String ANNOTATION_NS="http://www.w3.org/2000/10/annotation-ns#"; + public static String RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + public static String MPIWG_annot="http://ontologies.mpiwg-berlin.mpg.de/annotations/"; + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/Errors/TripleStoreSearchError.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,10 @@ +package de.mpiwg.itgroup.annotationManager.Errors; + +public class TripleStoreSearchError extends Error { + + /** + * + */ + private static final long serialVersionUID = -2082690329117989805L; + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/Errors/TripleStoreStoreError.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,5 @@ +package de.mpiwg.itgroup.annotationManager.Errors; + +public class TripleStoreStoreError extends Error { + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/Errors/XPointerError.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,10 @@ +package de.mpiwg.itgroup.annotationManager.Errors; + +public class XPointerError extends Error { + + /** + * + */ + private static final long serialVersionUID = 6385261924906311174L; + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/RDFHandling/Convert.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,239 @@ +package de.mpiwg.itgroup.annotationManager.RDFHandling; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.apache.log4j.Logger; +import org.openrdf.repository.RepositoryException; +import org.restlet.Context; +import org.restlet.engine.component.ChildContext; + +import de.mpiwg.itgroup.annotationManager.Constants.NS; +import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreStoreError; +import de.mpiwg.itgroup.annotationManager.Errors.XPointerError; +import de.mpiwg.itgroup.nimanager.exceptions.TripleStoreHandlerException; +import de.mpiwg.itgroup.nimanager.owl.TripleStoreHandler; +import de.mpiwg.itgroup.nimanager.owl.TripleStoreHandler.Quadruple; +import de.mpiwg.itgroup.nimanager.owl.TripleStoreHandler.LiteralQuadruple; + +/** + * @author dwinter + * + * Klasse zum Konvertieren von Annotationen zum mpiwg RDF-Format: + * http://ontologies.mpiwg-berlin.mpg.de/annotations/ + */ + +public class Convert { + private String ctx; + private Logger logger = Logger.getRootLogger(); + private String urlBase="http://ontologies.mpiwg-berlin.mpg.de/annotations/"; //TODO should go into config + public Convert(String c){ + ctx=c; + } + + /** + * Fasst alle Parameter zusammen, die eine Annotation bilden + * @author dwinter + * + */ + static public class Annotation { + public String xpointer=null; //if queried xpointer should contain the first xpointer in the xpointers list, if there is more than one. + public String creator=null; + public String time=null; + public String text=null; + public String type=null; + public String url; + public List<String> xpointers=null; // list of xpointers on the page url, can be empty or null if there is only one. + + /** + * @param xpointer Beschreibt die Annotation + * @param creator Username des Creators + * @param time Erstellungszeit, wenn null wird das aktuelle Datum verwenden beim Konvertieren + * @param text der Annotation + * @param type Annotationstype (Entsprechend den in http://www.w3.org/2000/10/annotationType# definierten.) + * @param url Url einer Annotation + */ + public Annotation(String xpointer, String creator, String time, String text, String type, String url){ + this.xpointer=xpointer; + this.creator=creator; + this.time=time; + this.text=text; + this.type=type; + this.url=url; + } + + /** + * @param xpointer Beschreibt die Annotation + * @param creator Username des Creators + * @param time Erstellungszeit, wenn null wird das aktuelle Datum verwenden beim Konvertieren + * @param text der Annotation + * @param type Annotationstype (Entsprechend den in http://www.w3.org/2000/10/annotationType# definierten.) + */ + public Annotation(String xpointer, String creator, String time, String annot, String type){ + this.xpointer=xpointer; + this.creator=creator; + this.time=time; + this.text=annot; + this.type=type; + this.url=null; + } + + + } + private String annotUrl=null; + + /** + * + * @param xpointer Beschreibt die Annotation + * @param creator Username des Creators + * @param time Erstellungszeit, wenn null wird das aktuelle Datum verwenden beim Konvertieren + * @param text der Annotation + * @param type Annotationstype (Entsprechend den in http://www.w3.org/2000/10/annotationType# definierten.) + * @return + */ + + private List<Quadruple> annot2quadruple(String xpointer, String creator, String time, String annot, String type){ + return annot2quadruple(new Annotation(xpointer, creator, time, annot, type)); + } + + + /** + * @param annot + * @return + */ + public List<Quadruple> annot2quadruple(Annotation annot){ + List<Quadruple> retQuad = new ArrayList<Quadruple>(); + + String annotation = createRessourceURL("annot:"); + + if (annot.time==null){ + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'"); + annot.time=format.format(Calendar.getInstance().getTime()); + + } + + //TODO: check type + retQuad.add(new Quadruple(annotation, NS.RDF+"type", NS.ANNOTATION_TYPE+annot.type, ctx)); + + //add author + retQuad.add(new LiteralQuadruple(annotation, NS.ANNOTATION_NS+"author", annot.creator, ctx)); + + // creation time + retQuad.add(new LiteralQuadruple(annotation, NS.ANNOTATION_NS+"created", annot.time, ctx)); + + String[] xpointerSplitted = annot.xpointer.split("#"); + + if (xpointerSplitted.length>2){ + annotUrl=null; + throw new XPointerError(); + } + + // now add the xpointers + retQuad.add(new Quadruple(annotation, NS.MPIWG_annot+"docuviewerText", xpointerSplitted[0], ctx)); + retQuad.add(new Quadruple(annotation, NS.MPIWG_annot+"textSelection", annot.xpointer, ctx)); + + String annotationtext =createRessourceURL("annotText:"); + + retQuad.add(new Quadruple(annotation, NS.ANNOTATION_NS+"body", annotationtext, ctx)); + + retQuad.add(new Quadruple(annotationtext, NS.RDF+"type", NS.MPIWG_annot+"StandardTextNote", ctx)); + + retQuad.add(new LiteralQuadruple(annotationtext, NS.MPIWG_annot+"containsText", annot.text, ctx)); + + for (Quadruple ret:retQuad){ + logger.debug(ret.toString()); + } + + annotUrl=annotation; + return retQuad; + } + + /** + * Erzeuge eine urn aus der aktullen Zeit in millis + * @return + */ + private String createRessourceURL(String prefix) { + + Calendar cal = Calendar.getInstance(); + + long time = cal.getTimeInMillis(); + + return String.format("%s%s%s", urlBase,prefix,time); + + + + } + + /** + * gibt nach die nach aufruf eines Converters erzeuge aktuelle url der annotation zurueck + * @return + */ + public String getAnnotUrl() { + + return annotUrl; + } + + /** + * @param args + */ + public static void main(String[] args) { + Convert myConvert = new Convert("http://annotations.rdf"); + List<Quadruple> rets = myConvert.annot2quadruple("http://mpdl-dev.mpiwg-berlin.mpg.de/ECHOdocuViewfullTest?url=/mpiwg/online/permanent/library/163127KK&viewMode=text&pn=7#xpointer(string-range(id("s1"), "", 66, 12))", "mbuchman", null, "myannot", "Example"); + for (Quadruple ret:rets){ + System.out.println(ret.toString()); + } + + } + + + public String storeAnnotation(Convert.Annotation annot) throws TripleStoreStoreError { + + //Convert convert = new Convert("<file:///annotations>"); + + + if ((annot.type==null) || annot.type.equals("")){ + annot.type="Comment"; + } + + List<Quadruple> annots = new ArrayList<Quadruple>(); + if (annot.text!=null && !annot.text.equals("")) + annots=annot2quadruple(annot); + if (annot.url!=null && !annot.url.equals("")) + annots.addAll(rel2quadruple(annot)); + + + + try { + ChildContext context = (ChildContext)Context.getCurrent(); + String user = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUser"); + String pw = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUserPassword"); + + TripleStoreHandler th = new TripleStoreHandler("jdbc:virtuoso://virtuoso.mpiwg-berlin.mpg.de:1111", user, pw); + + th.write(annots); + } catch (RepositoryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new TripleStoreStoreError(); + } catch (TripleStoreHandlerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new TripleStoreStoreError(); + } + + + + return getAnnotUrl(); +} + + + private List<Quadruple> rel2quadruple(Annotation annot) { + // TODO Auto-generated method stub + return new ArrayList<TripleStoreHandler.Quadruple>(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/RDFHandling/RDFSearcher.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,104 @@ +package de.mpiwg.itgroup.annotationManager.RDFHandling; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.apache.tiles.context.ListAttribute; +import org.openrdf.query.BindingSet; +import org.openrdf.query.TupleQueryResult; +import org.restlet.Context; +import org.restlet.engine.component.ChildContext; + +import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreSearchError; +import de.mpiwg.itgroup.annotationManager.RDFHandling.Convert.Annotation; +import de.mpiwg.itgroup.nimanager.exceptions.TripleStoreHandlerException; +import de.mpiwg.itgroup.nimanager.owl.TripleStoreHandler; + +public class RDFSearcher { + + private String urlBase="http://ontologies.mpiwg-berlin.mpg.de/annotations/"; //TODO should go into config + + private TripleStoreHandler th; + + private String context; + + private Logger logger= Logger.getRootLogger(); + + public RDFSearcher(String context) { + this.context=context; + } + + + + public List<Annotation> search(String uri, String user, String limit, + String offset) throws TripleStoreHandlerException, TripleStoreSearchError { + + List<Annotation> retAnnots = new ArrayList<Convert.Annotation>(); + ChildContext context = (ChildContext)Context.getCurrent(); + String tripleStoreUser = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUser"); + String tripleStorePW = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUserPassword"); + + th = new TripleStoreHandler("jdbc:virtuoso://virtuoso.mpiwg-berlin.mpg.de:1111", tripleStoreUser, tripleStorePW);//TODO should go into config + String queryString=""; + + String whereString = "?s ?p <http://www.w3.org/2000/10/annotationType#Comment>."; + //whereString +="?s <http://ontologies.mpiwg-berlin.mpg.de/annotations/docuviewerText> ?link."; + + if(uri!=null && !uri.equals("")){ + whereString +=String.format("?s <http://ontologies.mpiwg-berlin.mpg.de/annotations/docuviewerText> <%s>.",uri);} + else { + whereString +=String.format("?s <http://ontologies.mpiwg-berlin.mpg.de/annotations/docuviewerText> ?uri."); + } + whereString +=String.format("?s <http://ontologies.mpiwg-berlin.mpg.de/annotations/textSelection> ?xpointer."); + whereString +=String.format("?s <http://www.w3.org/2000/10/annotation-ns#body> ?annotText."); + + if(user!=null && !user.equals("")){ + whereString +=String.format("?s <http://www.w3.org/2000/10/annotation-ns#author> \"%s\".",user); + } else { + whereString +=String.format("?s <http://www.w3.org/2000/10/annotation-ns#author> ?author."); + } + + whereString +=String.format("?s <http://www.w3.org/2000/10/annotation-ns#created> ?created."); + + whereString +=String.format("?annotText <http://ontologies.mpiwg-berlin.mpg.de/annotations/containsText> ?text."); + + queryString=String.format("select distinct * where {%s}",whereString); + + + logger.debug("RDFSearcher:"+queryString); + + try { + TupleQueryResult results = th.querySPARQL(queryString); + + while (results.hasNext()) { + BindingSet result = results.next(); + String annotUri; + if(uri!=null && !uri.equals("")){ + annotUri=uri; + } else { + annotUri = result.getBinding("uri").getValue().stringValue(); + } + + String annotUser; + if(user!=null && !user.equals("")){ + annotUser=user; + } else { + annotUser = result.getBinding("author").getValue().stringValue(); + } + + + Annotation annot = new Annotation(result.getBinding("xpointer").getValue().stringValue(), + annotUser, result.getBinding("created").getValue().stringValue(), + result.getBinding("text").getValue().stringValue(), null, + annotUri); + retAnnots.add(annot); + } + } catch (Exception e) { + throw new TripleStoreSearchError(); + } + // TODO Auto-generated method stub + return retAnnots; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/restlet/AddAndSearchAnnotations.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,482 @@ +//TODO: handle XML-Post des Annoteaprotocolls http://www.w3.org/2001/Annotea/User/Protocol.html + +package de.mpiwg.itgroup.annotationManager.restlet; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.restlet.data.ClientInfo; +import org.restlet.data.Form; +import org.restlet.data.MediaType; +import org.restlet.data.Status; +import org.restlet.ext.json.JsonRepresentation; +import org.restlet.representation.Representation; +import org.restlet.representation.StringRepresentation; +import org.restlet.resource.Get; +import org.restlet.resource.Options; +import org.restlet.resource.Post; +import org.restlet.resource.ServerResource; +import org.restlet.security.User; + +import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreSearchError; +import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreStoreError; +import de.mpiwg.itgroup.annotationManager.RDFHandling.Convert; +import de.mpiwg.itgroup.annotationManager.RDFHandling.Convert.Annotation; +import de.mpiwg.itgroup.annotationManager.RDFHandling.RDFSearcher; +import de.mpiwg.itgroup.nimanager.exceptions.TripleStoreHandlerException; + +public class AddAndSearchAnnotations extends ServerResource { + + private Logger logger = Logger.getRootLogger(); + + /** + * + * json hash: username: name des users xpointer: xpointer auf den Ausschnitt + * (incl. der URL des Dokumentes) text: text der annotation annoturl: url + * auf eine Annotation falls extern + * + * @return + */ + + + @Options + public void doOptions(Representation entity) { + Form responseHeaders = (Form) getResponse().getAttributes().get( + "org.restlet.http.headers"); + if (responseHeaders == null) { + responseHeaders = new Form(); + getResponse().getAttributes().put("org.restlet.http.headers", + responseHeaders); + } + responseHeaders.add("Access-Control-Allow-Origin", "*"); + responseHeaders.add("Access-Control-Allow-Methods", "POST,OPTIONS,GET"); + responseHeaders.add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-Annotator-Account-Id, X-Annotator-User-Id, X-Annotator-Auth-Token-Valid-Until, X-Annotator-Auth-Token"); + responseHeaders.add("Access-Control-Allow-Credentials", "false"); + responseHeaders.add("Access-Control-Max-Age", "60"); + } + + @Get("json") + public Representation doGetHTML(Representation entity){ + + doOptions(entity); + Form form = getRequest().getResourceRef().getQueryAsForm(); + String uri = form.getFirstValue("uri"); + String user = form.getFirstValue("user"); + + String limit=form.getFirstValue("limit"); + String offset=form.getFirstValue("offset"); + + +// + RDFSearcher searcher = new RDFSearcher("file:///annotations"); //TODO should ge into config file + + JSONArray ja; + try { + + List<Convert.Annotation> annots=searcher.search(uri,user,limit,offset); + + ja = new JSONArray(); + for (Convert.Annotation annot:annots){ + JSONObject jo = new JSONObject(); + jo.put("text", annot.text); + jo.put("uri",annot.url); + + JSONObject userObject= new JSONObject(); + userObject.put("id",annot.creator); + + RestServer restServer = (RestServer) getApplication(); + String userName=restServer.getUserNameFromLdap(annot.creator); + userObject.put("name",userName); + + jo.put("user",userObject); + + List<String> xpointer = new ArrayList<String>(); + + if (annot.xpointers==null || annot.xpointers.size()==0) + xpointer.add(annot.xpointer); + else { + for(String xpointerString:annot.xpointers){ + xpointer.add(xpointerString); + } + } + jo.put("ranges", transformToRanges(xpointer)); + ja.put(jo); + } + } catch (TripleStoreHandlerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + setStatus(Status.SERVER_ERROR_INTERNAL,"TripleStoreHandler Error"); + return null; + } catch (TripleStoreSearchError e) { + // TODO Auto-generated catch block + e.printStackTrace(); + setStatus(Status.SERVER_ERROR_INTERNAL,"TripleStoreSearch Error"); + return null; + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + setStatus(Status.SERVER_ERROR_INTERNAL,"JSon Error"); + return null; + } + + JSONObject retObject = new JSONObject(); + try { + retObject.put("rows",ja); + retObject.put("total",ja.length()); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + setStatus(Status.SERVER_ERROR_INTERNAL,"JSon Error"); + return null; + } + + logger.debug("sending:"); + logger.debug(retObject); + return new JsonRepresentation(retObject); + } + + private JSONArray transformToRanges(List<String> xpointers) { + + JSONArray ja = new JSONArray(); + + Pattern rg = Pattern.compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)"); + Pattern rg1 = Pattern.compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)"); + + + + try { + for(String xpointer:xpointers){ + String decoded =URLDecoder.decode(xpointer,"utf-8"); + Matcher m=rg.matcher(decoded); + m.find(); + //if (m.matches()){ + { + JSONObject jo = new JSONObject(); + jo.put("start", m.group(1)); + jo.put("startOffset", m.group(2)); + jo.put("end", m.group(3)); + jo.put("endOffset", m.group(4)); + ja.put(jo); + //} + } + m=rg1.matcher(xpointer); + if (m.matches()){ + JSONObject jo = new JSONObject(); + jo.put("start", m.group(1)); + jo.put("startOffset", m.group(2)); + + ja.put(jo); + } + + + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + return ja; + + + + + + } + + @Post("json") + public Representation doPostJson(Representation entity) { + + String retVal = doPost(entity); + JSONObject jo; + try { + jo = new JSONObject("{\"annotUrl\":\"" + retVal + "\"}"); + } catch (JSONException e) { + setStatus(Status.SERVER_ERROR_INTERNAL); + return null; + } + JsonRepresentation retRep = new JsonRepresentation(jo); + return retRep; + } + + @Post("html") + public Representation doPostHtml(Representation entity) { + String retVal = doPost(entity); + if (retVal == null) { + return null; + } + String text = String.format( + "<html><body><a href=\"%s\">%s</a></body></html>", retVal + .replace(">", "").replace("<", ""), + retVal.replace(">", ">").replace("<", "<")); + Representation retRep = new StringRepresentation(text, + MediaType.TEXT_HTML); + return retRep; + } + + public String doPost(Representation entity) { + Convert.Annotation annot; + // versuche basic authentifizierung und hole den Benutzer von dort. + + // User authUser;= handleBasicAuthentification(entity); + + if (entity.getMediaType().equals(MediaType.APPLICATION_JSON)) { + + JsonRepresentation jrep; + try { + jrep = new JsonRepresentation(entity); + } catch (IOException e1) { + setStatus(Status.SERVER_ERROR_INTERNAL); + return null; + } + + // try { + // logger.debug(jrep.getText()); + // } catch (IOException e1) { + // // TODO Auto-generated catch block + // e1.printStackTrace(); + // } + // + + try { + JSONObject jo = jrep.getJsonObject(); + String mode = jo.getString("mode"); // hole modus + if (mode==null || mode.equals("")) + mode="annotea"; // default mode (annotea) TODO make this configurable + + if (mode.equals("annotator") ) { // annotator format + annot = handleAnnotatorSchema(jo, entity); + logger.debug("storing annotator object"); + logger.debug(jo); + } else if (mode.equals("annotea")){ + annot = handleAnnotea(jo, entity); + } else { + setStatus(Status.CLIENT_ERROR_BAD_REQUEST,"mode "+mode+"not supported!"); + return null; + } + + } catch (JSONException e) { + setStatus(Status.CLIENT_ERROR_BAD_REQUEST); + return null; + } + + } else if (entity.getMediaType().equals(MediaType.APPLICATION_WWW_FORM)) { + annot = handleForm(entity); + + } else { + setStatus(Status.CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE); + + return null; + } + + if (annot==null){ + return null; + } + if (annot.xpointer == null || annot.creator == null) { + setStatus(Status.CLIENT_ERROR_BAD_REQUEST); + + return null; + } + + + + try { + return new Convert("file:///annotations").storeAnnotation(annot); + } catch (TripleStoreStoreError e) { + e.printStackTrace(); + setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error"); + return null; + } + } + + protected Convert.Annotation handleForm(Representation entity) { + Convert.Annotation annot; + Form form = new Form(entity); + String username = form.getValues("username"); + String password = form.getValues("password"); + String xpointer = form.getValues("xpointer"); + String text = form.getValues("text"); + String url = form.getValues("url"); + String type = form.getValues("type"); + RestServer restServer = (RestServer) getApplication(); + + // falls user and password nicht null sind: + User userFromForm = null; + if (username != null && password != null) { + if (restServer.authenticate(username, password, getRequest())) { + userFromForm = new User(username); + } + } + User authUser = null; + + if (userFromForm == null) { + authUser = handleBasicAuthentification(entity); + } + + // weder BasicAuth noch FormAuth + if (authUser == null && userFromForm == null) { + setStatus(Status.CLIENT_ERROR_FORBIDDEN); + return null; + } + + if (userFromForm != null) { + username = userFromForm.getIdentifier(); + } else { + username = authUser.getIdentifier(); + } + + annot = new Convert.Annotation(xpointer, username, null, text, + type, url); + return annot; + } + + @Post + public Representation doPostHtml2(Representation entity) { + return doPostHtml(entity); + } + + private User handleBasicAuthentification(Representation entity) { + RestServer restServer = (RestServer) getApplication(); + if (!restServer.authenticate(getRequest(), getResponse())) { + // Not authenticated + return null; + } + + ClientInfo ci = getRequest().getClientInfo(); + logger.debug(ci); + return getRequest().getClientInfo().getUser(); + + } + + /** + * using a minimal annotation format based on the annotea specification + * + * @param jo + * must contain xpointer, text,url,type and can contain a + * username, if not the username form the authentification will + * be used. + * @param authUser + * user object + * @return + * @throws JSONException + */ + public Annotation handleAnnotea(JSONObject jo, Representation entity) + throws JSONException { + + User authUser = handleBasicAuthentification(entity); + String username = jo.getString("username"); // not required, if no + // username given authuser + // will be used. + String xpointer = jo.getString("xpointer"); + String text = null; + if (jo.has("text")) + text = jo.getString("text"); + + String url = null; + if (jo.has("url")) + url = jo.getString("url"); + + String type = null; + if (jo.has("type")) + type = jo.getString("type"); + + if (username == null) + username = authUser.getIdentifier(); + + return new Convert.Annotation(xpointer, username, null, text, type, url); + } + + /** + * uses the specification from the annotator project. + * + * @see{https://github.com/okfn/annotator/wiki/Annotation-format The user + * object must + * contain an + * id and + * password or + * basic + * authentification + * is used. + * + * @param jo + * @param authUser + * @return + * @throws JSONException + */ + public Convert.Annotation handleAnnotatorSchema(JSONObject jo, + Representation entity) throws JSONException { + Convert.Annotation annot; + String url = jo.getString("uri"); + String text = jo.getString("text"); + + String username = null; + if (jo.has("user")) { // not required, if no username given authuser + // will be used otherwise username and password + // has to be submitted + JSONObject user = jo.getJSONObject("user"); + if (user.has("id")) { + username = user.getString("id"); + if(!user.has("password")){ + User authUser = handleBasicAuthentification(entity); + if (authUser==null){ + setStatus(Status.CLIENT_ERROR_FORBIDDEN); + return null; + } + username = authUser.getIdentifier(); + } else { + String password = user.getString("password"); + if (!((RestServer) getApplication()).authenticate(username, + password, getRequest())) { + setStatus(Status.CLIENT_ERROR_FORBIDDEN); + return null; + } + } + } + + } else { + User authUser = handleBasicAuthentification(entity); + if (authUser == null) { + setStatus(Status.CLIENT_ERROR_FORBIDDEN); + return null; + } + username = authUser.getIdentifier(); + } + + String xpointer; + if (jo.has("ranges")) { + JSONObject ranges = jo.getJSONArray("ranges").getJSONObject(0); + String start = ranges.getString("start"); + String end = ranges.getString("end"); + String startOffset = ranges.getString("startOffset"); + String endOffset = ranges.getString("endOffset"); + + try { + xpointer = url+"#"+ + URLEncoder.encode(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"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + setStatus(Status.SERVER_ERROR_INTERNAL); + return null; + } + } else { + xpointer = url; + } + return new Convert.Annotation(xpointer, username, null, text, null); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/restlet/Dummy.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,45 @@ +package de.mpiwg.itgroup.annotationManager.restlet; + +import java.io.FileWriter; +import java.io.IOException; + +import org.restlet.representation.Representation; +import org.restlet.representation.StringRepresentation; +import org.restlet.resource.Get; +import org.restlet.resource.Post; +import org.restlet.resource.ServerResource; + +public class Dummy extends ServerResource { + + @Post + public Representation doPost(Representation entity){ + + try { + FileWriter fh = new FileWriter("/tmp/input", true); + fh.write(entity.toString()); + fh.write(entity.getText()); + fh.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return new StringRepresentation("thanks"); + } + + + @Get + public Representation doGet(Representation entity){ + + try { + FileWriter fh = new FileWriter("/tmp/input", true); + fh.write(entity.toString()); + fh.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return new StringRepresentation("thanks"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/restlet/MyCallBackHandler.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,48 @@ +package de.mpiwg.itgroup.annotationManager.restlet; + +import java.io.IOException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.ConfirmationCallback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.TextOutputCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +public class MyCallBackHandler implements CallbackHandler { + + + private String username; + private String password; + + public MyCallBackHandler(String username, String password) { + this.username=username; + this.password=password; + } + + @Override + public void handle(Callback[] callbacks) throws IOException, + UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof TextOutputCallback) { + + // do nothing + } else if (callbacks[i] instanceof NameCallback) { + + NameCallback nc = (NameCallback)callbacks[i]; + nc.setName(username); + + } else if (callbacks[i] instanceof PasswordCallback) { + + PasswordCallback nc = (PasswordCallback)callbacks[i]; + nc.setPassword(password.toCharArray()); + } else { + throw new UnsupportedCallbackException + (callbacks[i], "Unrecognized Callback"); + } + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/restlet/RestServer.java Tue Nov 22 15:47:57 2011 +0100 @@ -0,0 +1,222 @@ +package de.mpiwg.itgroup.annotationManager.restlet; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Hashtable; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.Configuration; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.restlet.Application; +import org.restlet.Context; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.Restlet; + +import org.restlet.data.ChallengeScheme; +import org.restlet.data.ClientInfo; +import org.restlet.ext.jaas.JaasVerifier; +import org.restlet.routing.Router; +import org.restlet.routing.Template; +import org.restlet.routing.TemplateRoute; +import org.restlet.security.ChallengeAuthenticator; +import org.restlet.security.MapVerifier; +import org.restlet.security.User; +import org.restlet.security.Verifier; + +import com.sun.org.apache.xalan.internal.xsltc.runtime.Attributes; +import com.sun.security.auth.login.ConfigFile; + + + + +public class RestServer extends Application { + + + private ChallengeAuthenticator authenticator; + private CallbackHandler callbackHandler; + + /** Erzeuge einen Authenticator + * @return + */ + private ChallengeAuthenticator createAuthenticator() { + Context context = getContext(); + boolean optional = true; + ChallengeScheme challengeScheme = ChallengeScheme.HTTP_BASIC; + String realm = "Annotation Service"; + + // MapVerifier isn't very secure; see docs for alternatives + //MapVerifier verifier = new MapVerifier(); + //verifier.getLocalSecrets().put("user", "password".toCharArray()); + + JaasVerifier verifier = new JaasVerifier("BasicJaasAuthenticationApplication"); + + + Configuration jaasConfig; + jaasConfig = createConfiguration(); + + + verifier.setConfiguration(jaasConfig); + verifier.setUserPrincipalClassName("com.sun.security.auth.UserPrincipal"); + + ChallengeAuthenticator auth = new ChallengeAuthenticator(context, optional, challengeScheme, realm, verifier) { + @Override + protected boolean authenticate(Request request, Response response) { + if (request.getChallengeResponse() == null) { + return false; + } else { + return super.authenticate(request, response); + } + } + }; + + return auth; + } + + protected Configuration createConfiguration() { + Configuration jaasConfig; + URI confUri; + try { + confUri = new URI("file:///etc/jaasAuth.conf"); //TODO shoould be configurable + } catch (URISyntaxException e) { + e.printStackTrace(); + confUri = null; + } + + jaasConfig= new ConfigFile(confUri); + return jaasConfig; + } + + public RestServer(Context parentContext){ + super(parentContext); + + Logger rl = Logger.getRootLogger(); + BasicConfigurator.configure(); + rl.setLevel(Level.DEBUG); + + + } + + public synchronized Restlet createInboundRoot(){ + this.authenticator = createAuthenticator(); + + + Router router = new Router(getContext()); + + router.attach("/annotations",AddAndSearchAnnotations.class); + router.attach("/search",AddAndSearchAnnotations.class); // annotator api askes for different uris for search and adding + router.attach("/dummy",Dummy.class); + + authenticator.setNext(router); + return authenticator; + + + + } + + public boolean authenticate(Request request, Response response) { + if (!request.getClientInfo().isAuthenticated()) { + authenticator.challenge(response, false); + return false; + } + + if(request.getClientInfo().getUser()==null) //FIXME sometimes ist authenticated true, but no user + { + authenticator.challenge(response, false); + return false; + } + return true; + } + + public boolean authenticate(String username, String password,Request request) { + LoginContext lc; + + try { + Configuration conf = createConfiguration(); + + lc = new LoginContext("BasicJaasAuthenticationApplication", null, new MyCallBackHandler(username,password),conf); + lc.login(); + } catch (LoginException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + + Subject subject = lc.getSubject(); + ClientInfo clientInfo = new ClientInfo(); + User user = new User(username); + clientInfo.setAuthenticated(true); + clientInfo.setUser(user); + + request.setClientInfo(clientInfo); + return true; + } + + public String getUserNameFromLdap(String creator) { + String retString=creator; // falls nichts gefunden wird einfach den creator zurueckgeben + Hashtable<String,String> env = new Hashtable<String,String>(); + String sp = "com.sun.jndi.ldap.LdapCtxFactory"; + env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, sp); + + String ldapUrl = "ldap://mpiwgldap.mpiwg-berlin.mpg.de/dc=mpiwg-berlin,dc=mpg,dc=de";//TODO should go into config file + env.put(javax.naming.Context.PROVIDER_URL, ldapUrl); + + DirContext dctx; + try { + dctx = new InitialDirContext(env); + } catch (NamingException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + return retString; + } + + String base = "ou=People"; + + SearchControls sc = new SearchControls(); + String[] attributeFilter = { "cn", "mail" }; + sc.setReturningAttributes(attributeFilter); + sc.setSearchScope(SearchControls.SUBTREE_SCOPE); + + String filter = "(uid="+creator+")"; + + try { + NamingEnumeration<SearchResult> results = dctx.search(base, filter, sc); + while (results.hasMore()) { + SearchResult sr = (SearchResult) results.next(); + javax.naming.directory.Attributes attrs = sr.getAttributes(); + + Attribute attr = attrs.get("cn"); + retString=(String) attr.get(); + } + } catch (NamingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + dctx.close(); + } catch (NamingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return retString; + } + +}