@GET @Path("search/find") @Produces("application/xml") public List<Match> find( @QueryParam("q") String query, @QueryParam("corpora") String rawCorpusNames, @DefaultValue("0") @QueryParam("offset") String offsetRaw, @DefaultValue("10") @QueryParam("limit") String limitRaw) throws IOException { requiredParameter(query, "q", "AnnisQL query"); requiredParameter(rawCorpusNames, "corpora", "comma separated list of corpus names"); Subject user = SecurityUtils.getSubject(); List<String> corpusNames = splitCorpusNamesFromRaw(rawCorpusNames); for (String c : corpusNames) { user.checkPermission("query:find:" + c); } int offset = Integer.parseInt(offsetRaw); int limit = Integer.parseInt(limitRaw); QueryData data = queryDataFromParameters(query, rawCorpusNames); data.setCorpusConfiguration(annisDao.getCorpusConfiguration()); data.addExtension(new LimitOffsetQueryData(offset, limit)); long start = new Date().getTime(); List<Match> matches = annisDao.find(data); long end = new Date().getTime(); logQuery("FIND", query, splitCorpusNamesFromRaw(rawCorpusNames), end - start); return matches; }
/** * Get the {@link QueryData} from a query and the corpus names * * @param query The AQL query. * @param rawCorpusNames The name of the toplevel corpus names seperated by ",". * @return calculated {@link QueryData} for the given parametes. * @throws WebApplicationException Thrown if some corpora are unknown to the system. */ private QueryData queryDataFromParameters(String query, String rawCorpusNames) throws WebApplicationException { List<String> corpusNames = splitCorpusNamesFromRaw(rawCorpusNames); List<Long> corpusIDs = annisDao.mapCorpusNamesToIds(corpusNames); if (corpusIDs.size() != corpusNames.size()) { throw new WebApplicationException( Response.status(Response.Status.NOT_FOUND) .type("text/plain") .entity("one ore more corpora are unknown to the system") .build()); } return annisDao.parseAQL(query, corpusIDs); }
/** * Get a graph as {@link SaltProject} of a set of Salt IDs. * * @param saltIDs saltIDs must have at least one saltId, more than one id are separated by + or * space * @param leftRaw left context parameter * @param rightRaw right context parameter * @return the graph of this hit. */ @POST @Path("search/subgraph") @Produces({"application/xml", "application/xmi+xml", "application/xmi+binary"}) public SaltProject subgraph(final SubgraphQuery query) { // some robustness stuff if (query == null) { throw new WebApplicationException( Response.status(Response.Status.BAD_REQUEST) .type(MediaType.TEXT_PLAIN) .entity("missing required request body") .build()); } QueryData data = new QueryData(); data.addExtension( new AnnotateQueryData(query.getLeft(), query.getRight(), query.getSegmentationLayer())); Set<String> corpusNames = new TreeSet<String>(); for (SaltURIGroup singleMatch : query.getMatches().getGroups().values()) { // collect list of used corpora and created pseudo QueryNodes for each URI List<QueryNode> pseudoNodes = new ArrayList<QueryNode>(singleMatch.getUris().size()); for (java.net.URI u : singleMatch.getUris()) { pseudoNodes.add(new QueryNode()); corpusNames.add(CommonHelper.getCorpusPath(u).get(0)); } data.addAlternative(pseudoNodes); } Subject user = SecurityUtils.getSubject(); for (String c : corpusNames) { user.checkPermission("query:subgraph:" + c); } List<String> corpusNamesList = new LinkedList<String>(corpusNames); List<Long> corpusIDs = annisDao.mapCorpusNamesToIds(corpusNamesList); data.setCorpusList(corpusIDs); data.addExtension(query.getMatches()); long start = new Date().getTime(); SaltProject p = annisDao.graph(data); long end = new Date().getTime(); logQuery("SUBGRAPH", "", corpusNamesList, end - start); return p; }
/** * Log the successful initialization of this bean. * * <p>XXX: This should be a private method annotated with <tt>@PostConstruct</tt>, but that * doesn't seem to work. As a work-around, the method is called by Spring as an init-method. */ public void init() { // check version of PostgreSQL annisDao.checkDatabaseVersion(); // log a message after successful startup log.info("ANNIS QueryService loaded."); }
/** * Get an Annis Binary object identified by its id. * * @param id * @param rawOffset the part we want to start from, we start from 0 * @param rawLength how many bytes we take * @return AnnisBinary */ @GET @Path("corpora/{top}/{document}/binary/{offset}/{length}") @Produces("application/xml") public AnnisBinary binary( @PathParam("top") String toplevelCorpusName, @PathParam("document") String corpusName, @PathParam("offset") String rawOffset, @PathParam("length") String rawLength, @QueryParam("mime") String mimeType) { Subject user = SecurityUtils.getSubject(); user.checkPermission("query:binary:" + toplevelCorpusName); int offset = Integer.parseInt(rawOffset); int length = Integer.parseInt(rawLength); AnnisBinary bin; log.debug( "fetching " + (length / 1024) + "kb (" + offset + "-" + (offset + length) + ") from binary " + toplevelCorpusName + "/" + corpusName); bin = annisDao.getBinary(toplevelCorpusName, corpusName, mimeType, offset + 1, length); log.debug("fetch successfully"); return bin; }
/** Get result as matrix in WEKA (ARFF) format. */ @GET @Path("search/matrix") @Produces("text/plain") public String matrix( @QueryParam("q") String query, @QueryParam("corpora") String rawCorpusNames, @QueryParam("metakeys") String rawMetaKeys) { requiredParameter(query, "q", "AnnisQL query"); requiredParameter(rawCorpusNames, "corpora", "comma separated list of corpus names"); Subject user = SecurityUtils.getSubject(); List<String> corpusNames = splitCorpusNamesFromRaw(rawCorpusNames); for (String c : corpusNames) { user.checkPermission("query:matrix:" + c); } QueryData data = queryDataFromParameters(query, rawCorpusNames); MatrixQueryData ext = new MatrixQueryData(); if (rawMetaKeys != null) { ext.setMetaKeys(splitMatrixKeysFromRaw(rawMetaKeys)); } data.addExtension(ext); long start = new Date().getTime(); List<AnnotatedMatch> matches = annisDao.matrix(data); long end = new Date().getTime(); logQuery("MATRIX", query, splitCorpusNamesFromRaw(rawCorpusNames), end - start); if (matches.isEmpty()) { return "(empty)"; } else { return WekaHelper.exportAsArff(matches); } }
@GET @Path("corpora/{top}/metadata") @Produces("application/xml") public List<Annotation> getMetadata(@PathParam("top") String toplevelCorpusName) { Subject user = SecurityUtils.getSubject(); user.checkPermission("query:meta:" + toplevelCorpusName); return annisDao.listCorpusAnnotations(toplevelCorpusName); }
/** * Get the Metadata of an Annis Binary object identified by its id. This function calls * getBinary(long id, 1, 1), so this function does not work, if the specs of getBinary(long id, * int offset,int length) changed. * * @param id * @return AnnisBinaryMetaData */ @GET @Path("corpora/{top}/{document}/binary/meta") @Produces("application/xml") public List<AnnisBinaryMetaData> binaryMeta( @PathParam("top") String toplevelCorpusName, @PathParam("document") String documentName) { Subject user = SecurityUtils.getSubject(); user.checkPermission("query:binary:" + toplevelCorpusName); return annisDao.getBinaryMeta(toplevelCorpusName, documentName); }
@GET @Path("corpora/{top}/annotations") @Produces("application/xml") public List<AnnisAttribute> annotations( @PathParam("top") String toplevelCorpus, @DefaultValue("false") @QueryParam("fetchvalues") String fetchValues, @DefaultValue("false") @QueryParam("onlymostfrequentvalues") String onlyMostFrequentValues) { Subject user = SecurityUtils.getSubject(); user.checkPermission("query:annotations:" + toplevelCorpus); List<String> list = new LinkedList<String>(); list.add(toplevelCorpus); List<Long> corpusList = annisDao.mapCorpusNamesToIds(list); return annisDao.listAnnotations( corpusList, Boolean.parseBoolean(fetchValues), Boolean.parseBoolean(onlyMostFrequentValues)); }
@GET @Path("resolver/{corpusName}/{namespace}/{type}") @Produces("application/xml") public List<ResolverEntry> resolver( @PathParam("corpusName") String corpusName, @PathParam("namespace") String namespace, @PathParam("type") String type) { ResolverEntry.ElementType enumType = ResolverEntry.ElementType.valueOf(type); SingleResolverRequest r = new SingleResolverRequest(corpusName, namespace, enumType); return annisDao.getResolverEntries(r); }
@GET @Path("corpora/{top}/config") @Produces("application/xml") public CorpusConfig corpusconfig(@PathParam("top") String toplevelName) { Subject user = SecurityUtils.getSubject(); user.checkPermission("query:config:" + toplevelName); Map<String, String> tmp = annisDao.getCorpusConfiguration(toplevelName); CorpusConfig result = new CorpusConfig(); result.setConfig(tmp); return result; }
@GET @Path("corpora") @Produces("application/xml") public List<AnnisCorpus> corpora() { List<AnnisCorpus> allCorpora = annisDao.listCorpora(); List<AnnisCorpus> allowedCorpora = new LinkedList<AnnisCorpus>(); // filter by which corpora the user is allowed to access Subject user = SecurityUtils.getSubject(); for (AnnisCorpus c : allCorpora) { if (user.isPermitted("query:*:" + c.getName())) { allowedCorpora.add(c); } } return allowedCorpora; }
@GET @Path("graphs/{top}/{doc}") @Produces({"application/xml", "application/xmi+xml", "application/xmi+binary"}) public SaltProject graph( @PathParam("top") String toplevelCorpusName, @PathParam("doc") String documentName) { Subject user = SecurityUtils.getSubject(); user.checkPermission("query:subgraph:" + toplevelCorpusName); try { long start = new Date().getTime(); SaltProject p = annisDao.retrieveAnnotationGraph(toplevelCorpusName, documentName); long end = new Date().getTime(); logQuery("GRAPH", toplevelCorpusName, documentName, end - start); return p; } catch (Exception ex) { log.error("error when accessing graph " + toplevelCorpusName + "/" + documentName, ex); throw new WebApplicationException(ex); } }
@GET @Path("search/count") @Produces("application/xml") public Response count( @QueryParam("q") String query, @QueryParam("corpora") String rawCorpusNames) { requiredParameter(query, "q", "AnnisQL query"); requiredParameter(rawCorpusNames, "corpora", "comma separated list of corpus names"); Subject user = SecurityUtils.getSubject(); List<String> corpusNames = splitCorpusNamesFromRaw(rawCorpusNames); for (String c : corpusNames) { user.checkPermission("query:count:" + c); } QueryData data = queryDataFromParameters(query, rawCorpusNames); long start = new Date().getTime(); MatchAndDocumentCount count = annisDao.countMatchesAndDocuments(data); long end = new Date().getTime(); logQuery("COUNT", query, splitCorpusNamesFromRaw(rawCorpusNames), end - start); return Response.ok(count).type(MediaType.APPLICATION_XML_TYPE).build(); }
@GET @Path("search/annotate") @Produces("application/xml") public SaltProject annotate( @QueryParam("q") String query, @QueryParam("corpora") String rawCorpusNames, @DefaultValue("0") @QueryParam("offset") String offsetRaw, @DefaultValue("10") @QueryParam("limit") String limitRaw, @DefaultValue("5") @QueryParam("left") String leftRaw, @DefaultValue("5") @QueryParam("right") String rightRaw, @QueryParam("seglayer") String segmentationLayer) throws IOException { requiredParameter(query, "q", "AnnisQL query"); requiredParameter(rawCorpusNames, "corpora", "comma separated list of corpus names"); Subject user = SecurityUtils.getSubject(); List<String> corpusNames = splitCorpusNamesFromRaw(rawCorpusNames); for (String c : corpusNames) { user.checkPermission("query:annotate:" + c); } int offset = Integer.parseInt(offsetRaw); int limit = Integer.parseInt(limitRaw); int left = Math.min(maxContext, Integer.parseInt(leftRaw)); int right = Math.min(maxContext, Integer.parseInt(rightRaw)); QueryData data = queryDataFromParameters(query, rawCorpusNames); String logParameters = createAnnotateLogParameters(left, right, offset, limit); data.addExtension(new LimitOffsetQueryData(offset, limit)); data.addExtension(new AnnotateQueryData(left, right, segmentationLayer)); long start = new Date().getTime(); SaltProject p = annisDao.annotate(data); long end = new Date().getTime(); logQuery( "ANNOTATE", query, splitCorpusNamesFromRaw(rawCorpusNames), end - start, logParameters); return p; }
/** * Return true if this is a valid query or throw exception when invalid * * @param query Query to check for validity * @return */ @GET @Path("check") public String check(@QueryParam("q") String query) { annisDao.parseAQL(query, new LinkedList<Long>()); return "ok"; }