# HG changeset patch # User casties # Date 1332165028 -3600 # Node ID 11baadcdd2c8bbdd9acd3cf9cac30120640f68ac # Parent 97f68ab3430ffc1534332fb406057f155c5a621a start of new Annotator API implementation. diff -r 97f68ab3430f -r 11baadcdd2c8 src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java Mon Mar 19 14:50:28 2012 +0100 @@ -0,0 +1,161 @@ +/** + * Base class for Annotator resource classes. + */ +package de.mpiwg.itgroup.annotationManager.restlet; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.restlet.data.Form; +import org.restlet.representation.Representation; +import org.restlet.resource.Options; +import org.restlet.resource.ServerResource; + +import de.mpiwg.itgroup.annotationManager.Constants.NS; +import de.mpiwg.itgroup.annotationManager.RDFHandling.Convert; + +/** + * Base class for Annotator resource classes. + * + * @author dwinter, casties + * + */ +public abstract class AnnotatorResourceImpl extends ServerResource { + + protected String getAllowedMethodsForHeader() { + return "OPTIONS,GET,POST"; + } + + /** + * Handle options request to allow CORS for AJAX. + * + * @param entity + */ + @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-Methods", + getAllowedMethodsForHeader()); + // echo back Origin and Request-Headers + Form requestHeaders = (Form) getRequest().getAttributes().get( + "org.restlet.http.headers"); + String origin = requestHeaders.getFirstValue("Origin", true); + if (origin == null) { + responseHeaders.add("Access-Control-Allow-Origin", "*"); + } else { + responseHeaders.add("Access-Control-Allow-Origin", origin); + } + String allowHeaders = requestHeaders.getFirstValue( + "Access-Control-Request-Headers", true); + if (allowHeaders != null) { + responseHeaders.add("Access-Control-Allow-Headers", allowHeaders); + } + responseHeaders.add("Access-Control-Allow-Credentials", "true"); + responseHeaders.add("Access-Control-Max-Age", "60"); + } + + /** + * Erzeugt aus einer Annotation, das fuer den Annotator notwendige + * JSON-Format + * + * @param annot + * @return + */ + protected JSONObject annot2AnnotatorJSON(Convert.Annotation annot) { + JSONObject jo = new JSONObject(); + try { + jo.put("text", annot.text); + jo.put("uri", annot.url); + + JSONObject userObject = new JSONObject(); + userObject.put("id", annot.creator); + + RestServer restServer = (RestServer) getApplication(); + + String userID = annot.creator; + if (userID.startsWith(NS.MPIWG_PERSONS)) { + userID = userID.replace(NS.MPIWG_PERSONS, ""); // entferne + // NAMESPACE + } + String userName = restServer.getUserNameFromLdap(userID); + userObject.put("name", userName); + + jo.put("user", userObject); + + List xpointer = new ArrayList(); + + 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)); + jo.put("id", annot.annotationUri); + return jo; + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + private JSONArray transformToRanges(List 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); + + if (m.find()) { + { + 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.find()) { + 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; + } + +} diff -r 97f68ab3430f -r 11baadcdd2c8 src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorSearch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorSearch.java Mon Mar 19 14:50:28 2012 +0100 @@ -0,0 +1,177 @@ +/** + * Implements the "search" uri of the Annotator API. + */ +package de.mpiwg.itgroup.annotationManager.restlet; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +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 de.mpiwg.itgroup.annotationManager.Errors.TripleStoreSearchError; +import de.mpiwg.itgroup.annotationManager.RDFHandling.Convert; +import de.mpiwg.itgroup.annotationManager.RDFHandling.RDFSearcher; +import de.mpiwg.itgroup.triplestoremanager.exceptions.TripleStoreHandlerException; + +/** + * Implements the "search" uri of the Annotator API. + * see + * + * @author casties + * + */ +public class AnnotatorSearch extends AnnotatorResourceImpl { + + private Logger logger = Logger.getRootLogger(); + + protected String getAllowedMethodsForHeader() { + return "OPTIONS,GET"; + } + + /** + * JSON content type result. + * + * @param entity + * @return + */ + @Get("json") + public Representation doGetJSON(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 annots=searcher.search(uri,user,limit,offset); + + ja = new JSONArray(); + for (Convert.Annotation annot:annots){ + JSONObject jo = annot2AnnotatorJSON(annot); + if (jo!=null){ + ja.put(annot2AnnotatorJSON(annot)); + } else { + setStatus(Status.SERVER_ERROR_INTERNAL,"JSON Error"); + return null; + } + } + } 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; + } + + JSONObject result = new JSONObject(); + try { + result.put("rows",ja); + result.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(result); + return new JsonRepresentation(result); + } + + /** + * HTML content type result. + * + * @param entity + * @return + */ + @Get("html") + 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"); + + try { + if (uri!=null){ + uri = URLDecoder.decode(uri, "utf-8"); + } + } catch (UnsupportedEncodingException e1) { + e1.printStackTrace(); + setStatus(Status.CLIENT_ERROR_NOT_ACCEPTABLE); + return null; + } + + RDFSearcher searcher = new RDFSearcher("file:///annotations"); //TODO should ge into config file + + String retString=""; + String lineFormat="" + + ""; + try { + + List annots=searcher.search(uri,user,limit,offset); + + for (Convert.Annotation annot:annots){ + + + RestServer restServer = (RestServer) getApplication(); + String userName=restServer.getUserNameFromLdap(annot.creator); + List xpointer = new ArrayList(); + + if (annot.xpointers==null || annot.xpointers.size()==0) + retString+=String.format(lineFormat, userName,userName,annot.url,annot.url,annot.time,annot.text,annot.xpointer,annot.xpointer,annot.annotationUri,annot.annotationUri); + else { + for(String xpointerString:annot.xpointers){ + retString+=String.format(lineFormat, userName,userName,annot.url,annot.url,annot.time,annot.text,xpointerString,xpointerString,annot.annotationUri,annot.annotationUri); + } + } + + } + } 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; + } + + retString+="
%s%s%s%s%s%s
"; + + logger.debug("sending:"); + logger.debug(retString); + return new StringRepresentation(retString,MediaType.TEXT_HTML); + } + + +} diff -r 97f68ab3430f -r 11baadcdd2c8 src/de/mpiwg/itgroup/annotationManager/restlet/RestServer.java --- a/src/de/mpiwg/itgroup/annotationManager/restlet/RestServer.java Mon Mar 19 12:01:39 2012 +0100 +++ b/src/de/mpiwg/itgroup/annotationManager/restlet/RestServer.java Mon Mar 19 14:50:28 2012 +0100 @@ -12,11 +12,7 @@ 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; @@ -29,21 +25,13 @@ 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.engine.component.ChildContext; import org.restlet.ext.jaas.JaasVerifier; -import org.restlet.routing.Redirector; 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; @@ -134,7 +122,8 @@ router.attach("/annotations",AddAndReadAnnotations.class); - router.attach("/search",SearchAnnotations.class); // annotator api askes for different uris for search and adding + router.attach("/search",AnnotatorSearch.class); // annotator api askes for different uris for search and adding + //router.attach("/search",SearchAnnotations.class); // annotator api askes for different uris for search and adding router.attach("/dummy",Dummy.class); //router.attach("",redirector);