Renamed web.controller package in core
Moved SearchNetworkEndpoint to core.service package.
Change-Id: I746fcb20aa92ab3252cfc06dcce1f404ef955de3
diff --git a/core/src/main/java/de/ids_mannheim/korap/core/service/AnnotationService.java b/core/src/main/java/de/ids_mannheim/korap/core/service/AnnotationService.java
index 1f6abd7..4730a4f 100644
--- a/core/src/main/java/de/ids_mannheim/korap/core/service/AnnotationService.java
+++ b/core/src/main/java/de/ids_mannheim/korap/core/service/AnnotationService.java
@@ -9,13 +9,13 @@
import org.springframework.stereotype.Service;
import de.ids_mannheim.korap.core.entity.AnnotationLayer;
+import de.ids_mannheim.korap.core.web.controller.AnnotationController;
import de.ids_mannheim.korap.dao.AnnotationDao;
import de.ids_mannheim.korap.dto.FoundryDto;
import de.ids_mannheim.korap.dto.LayerDto;
import de.ids_mannheim.korap.dto.converter.AnnotationConverter;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.web.controller.AnnotationController;
/** AnnotationService defines the logic behind {@link AnnotationController}.
*
diff --git a/core/src/main/java/de/ids_mannheim/korap/core/service/SearchNetworkEndpoint.java b/core/src/main/java/de/ids_mannheim/korap/core/service/SearchNetworkEndpoint.java
new file mode 100644
index 0000000..de6038e
--- /dev/null
+++ b/core/src/main/java/de/ids_mannheim/korap/core/service/SearchNetworkEndpoint.java
@@ -0,0 +1,87 @@
+package de.ids_mannheim.korap.core.service;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.apache.http.HttpStatus;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+
+@Service
+public class SearchNetworkEndpoint {
+
+ private final static Logger jlog = LogManager
+ .getLogger(SearchNetworkEndpoint.class);
+
+ @Autowired
+ private KustvaktConfiguration config;
+
+ public String search (String query) throws KustvaktException {
+ String networkEndpointURL = config.getNetworkEndpointURL();
+ if (networkEndpointURL == null || networkEndpointURL.isEmpty()) {
+ throw new KustvaktException(
+ StatusCodes.NETWORK_ENDPOINT_NOT_AVAILABLE,
+ "Network endpoint is not available");
+ }
+ else {
+ try {
+ URL url = new URL(networkEndpointURL);
+ HttpURLConnection connection = (HttpURLConnection) url
+ .openConnection();
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type",
+ "application/json; charset=UTF-8");
+ connection.setRequestProperty("Accept", "application/json");
+ connection.setDoOutput(true);
+ OutputStream os = connection.getOutputStream();
+ byte[] input = query.getBytes("utf-8");
+ os.write(input, 0, input.length);
+
+ String entity = null;
+ if (connection.getResponseCode() == HttpStatus.SC_OK) {
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(connection.getInputStream(),
+ "utf-8"));
+ StringBuilder response = new StringBuilder();
+ String responseLine = null;
+ while ((responseLine = br.readLine()) != null) {
+ response.append(responseLine.trim());
+ }
+ entity = response.toString();
+ }
+
+ if (entity != null && !entity.isEmpty()) {
+ return entity;
+ }
+ else {
+ String message = connection.getResponseCode() + " "
+ + connection.getResponseMessage();
+ jlog.warn("Search on network endpoint failed "
+ + networkEndpointURL + ". Message: " + message);
+
+ throw new KustvaktException(
+ StatusCodes.SEARCH_NETWORK_ENDPOINT_FAILED,
+ "Failed searching at network endpoint: "
+ + networkEndpointURL,
+ message);
+ }
+ }
+ catch (Exception e) {
+ throw new KustvaktException(
+ StatusCodes.SEARCH_NETWORK_ENDPOINT_FAILED,
+ "Failed searching at network endpoint: "
+ + networkEndpointURL,
+ e.getCause());
+ }
+ }
+ }
+}
diff --git a/core/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java b/core/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
index e6d2368..96b5f62 100644
--- a/core/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
+++ b/core/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
@@ -40,7 +40,6 @@
import de.ids_mannheim.korap.utils.JsonUtils;
import de.ids_mannheim.korap.web.ClientsHandler;
import de.ids_mannheim.korap.web.SearchKrill;
-import de.ids_mannheim.korap.web.SearchNetworkEndpoint;
@Service
public class SearchService extends BasicService{
@@ -418,7 +417,7 @@
User user = createUser(username, headers);
Pattern p = determineAvailabilityPattern(user);
- boolean match_only = foundries == null || foundries.isEmpty();
+// boolean match_only = foundries == null || foundries.isEmpty();
String results;
// try {
diff --git a/core/src/main/java/de/ids_mannheim/korap/core/web/controller/AnnotationController.java b/core/src/main/java/de/ids_mannheim/korap/core/web/controller/AnnotationController.java
new file mode 100644
index 0000000..26d51dc
--- /dev/null
+++ b/core/src/main/java/de/ids_mannheim/korap/core/web/controller/AnnotationController.java
@@ -0,0 +1,125 @@
+package de.ids_mannheim.korap.core.web.controller;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.web.utils.ResourceFilters;
+import de.ids_mannheim.korap.core.service.AnnotationService;
+import de.ids_mannheim.korap.dto.FoundryDto;
+import de.ids_mannheim.korap.dto.LayerDto;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.web.KustvaktResponseHandler;
+import de.ids_mannheim.korap.web.filter.APIVersionFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+
+/**
+ * Provides services regarding annotation related information.
+ *
+ * @author margaretha
+ *
+ */
+@Controller
+@Path("/{version}/annotation/")
+@ResourceFilters({APIVersionFilter.class, DemoUserFilter.class, PiwikFilter.class })
+@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+public class AnnotationController {
+
+ @Autowired
+ private KustvaktResponseHandler kustvaktResponseHandler;
+
+ @Autowired
+ private AnnotationService annotationService;
+
+ /**
+ * Returns information about all supported layers
+ *
+ * @return a json serialization of all supported layers
+ */
+ @GET
+ @Path("layers")
+ public List<LayerDto> getLayers () {
+ return annotationService.getLayerDtos();
+ }
+
+
+ /**
+ * Returns a list of foundry descriptions.
+ *
+ * @param codes
+ * foundry-layer code or a Kleene-star
+ * @param language
+ * 2-letter language code (description language)
+ * @return a list of foundry, layer, value information in json
+ */
+ @SuppressWarnings("unchecked")
+ @POST
+ @Path("description")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public List<FoundryDto> getFoundryDescriptions (String json) {
+ if (json == null || json.isEmpty()) {
+ throw kustvaktResponseHandler
+ .throwit(new KustvaktException(StatusCodes.MISSING_PARAMETER,
+ "Missing a json string.", ""));
+ }
+
+ JsonNode node;
+ try {
+ node = JsonUtils.readTree(json);
+ }
+ catch (KustvaktException e1) {
+ throw kustvaktResponseHandler.throwit(e1);
+ }
+
+ String language;
+ if (!node.has("language")) {
+ language = "en";
+ }
+ else {
+ language = node.get("language").asText();
+ if (language == null || language.isEmpty()) {
+ language = "en";
+ }
+ else if (!(language.equals("en") || language.equals("de"))) {
+ throw kustvaktResponseHandler.throwit(
+ new KustvaktException(StatusCodes.UNSUPPORTED_VALUE,
+ "Unsupported value:", language));
+ }
+ }
+
+ List<String> codes;
+ try {
+ codes = JsonUtils.convert(node.get("codes"), List.class);
+ }
+ catch (IOException | NullPointerException e) {
+ throw kustvaktResponseHandler.throwit(new KustvaktException(
+ StatusCodes.INVALID_ARGUMENT, "Bad argument:", json));
+ }
+ if (codes == null || codes.isEmpty()) {
+ throw kustvaktResponseHandler.throwit(
+ new KustvaktException(StatusCodes.MISSING_ATTRIBUTE,
+ "codes is null or empty", "codes"));
+ }
+
+ try {
+ return annotationService.getFoundryDtos(codes, language);
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ }
+}
+
diff --git a/core/src/main/java/de/ids_mannheim/korap/core/web/controller/SearchController.java b/core/src/main/java/de/ids_mannheim/korap/core/web/controller/SearchController.java
new file mode 100644
index 0000000..acddf23
--- /dev/null
+++ b/core/src/main/java/de/ids_mannheim/korap/core/web/controller/SearchController.java
@@ -0,0 +1,490 @@
+package de.ids_mannheim.korap.core.web.controller;// package
+ // de.ids_mannheim.korap.ext.web;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import de.ids_mannheim.korap.web.utils.ResourceFilters;
+import de.ids_mannheim.korap.web.utils.SearchResourceFilters;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.constant.OAuth2Scope;
+import de.ids_mannheim.korap.core.service.SearchService;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.service.OAuth2ScopeService;
+import de.ids_mannheim.korap.security.context.TokenContext;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.ServiceInfo;
+import de.ids_mannheim.korap.web.KustvaktResponseHandler;
+import de.ids_mannheim.korap.web.filter.APIVersionFilter;
+import de.ids_mannheim.korap.web.filter.AdminFilter;
+import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+
+/**
+ *
+ * @author hanl, margaretha, diewald
+ * @date 29/01/2014
+ * @lastUpdate 05/07/2019
+ *
+ */
+@Controller
+@Path("/")
+@ResourceFilters({ APIVersionFilter.class, AuthenticationFilter.class,
+ DemoUserFilter.class, PiwikFilter.class })
+public class SearchController {
+
+ private static final boolean DEBUG = false;
+
+ private static Logger jlog = LogManager.getLogger(SearchController.class);
+ private @Context ServletContext context;
+
+ @Autowired
+ private KustvaktResponseHandler kustvaktResponseHandler;
+
+ @Autowired
+ private SearchService searchService;
+ @Autowired
+ private OAuth2ScopeService scopeService;
+ @Autowired
+ private KustvaktConfiguration config;
+
+ @GET
+ @Path("{version}")
+ public Response index (){
+ return Response
+ .ok(config.getApiWelcomeMessage())
+ .header("X-Index-Revision", searchService.getIndexFingerprint())
+ .build();
+ }
+
+ @GET
+ @Path("{version}/info")
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public Response info (){
+ Map<String, Object> m = new HashMap<>();
+ m.put("latest_api_version", config.getCurrentVersion());
+ m.put("supported_api_versions", config.getSupportedVersions());
+ m.put("kustvakt_version", ServiceInfo.getInfo().getVersion());
+ m.put("krill_version", searchService.getKrillVersion());
+ m.put("koral_version", ServiceInfo.getInfo().getKoralVersion());
+ try {
+ return Response.ok(JsonUtils.toJSON(m)).build();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ }
+
+ @POST
+ @Path("{version}/index/close")
+ // overrides the whole filters
+ @ResourceFilters({APIVersionFilter.class,AdminFilter.class})
+ public Response closeIndexReader (){
+ try {
+ searchService.closeIndexReader();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ return Response.ok().build();
+ }
+
+
+// EM: This web service is DISABLED until there is a need for it.
+// ND: In case rewrite is supported, it could be used to check the authorization
+// scope without searching etc. In case not, it helps to compare queries in
+// different query languages.
+// MH: ref query parameter removed!
+// @GET
+// @Path("{version}/query")
+// @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public Response serializeQuery (@Context Locale locale,
+ @Context SecurityContext securityContext, @QueryParam("q") String q,
+ @QueryParam("ql") String ql, @QueryParam("v") String v,
+ @QueryParam("context") String context,
+ @QueryParam("cutoff") Boolean cutoff,
+ @QueryParam("count") Integer pageLength,
+ @QueryParam("offset") Integer pageIndex,
+ @QueryParam("page") Integer startPage,
+ @QueryParam("access-rewrite-disabled") boolean accessRewriteDisabled,
+ @QueryParam("cq") String cq) {
+ TokenContext ctx = (TokenContext) securityContext.getUserPrincipal();
+ try {
+ scopeService.verifyScope(ctx, OAuth2Scope.SERIALIZE_QUERY);
+ String result = searchService.serializeQuery(q, ql, v, cq,
+ pageIndex, startPage, pageLength, context, cutoff,
+ accessRewriteDisabled);
+ if (DEBUG){
+ jlog.debug("Query: " + result);
+ }
+ return Response.ok(result).build();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ }
+
+
+// This web service is DISABLED until there is a need for it.
+ @POST
+ @Path("{version}/search")
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ @SearchResourceFilters
+ public Response searchPost (@Context SecurityContext context,
+ @Context Locale locale,
+ @Context HttpHeaders headers,
+ String jsonld) {
+
+ if (DEBUG){
+ jlog.debug("Serialized search: " + jsonld);
+ }
+
+ TokenContext ctx = (TokenContext) context.getUserPrincipal();
+ try {
+ scopeService.verifyScope(ctx, OAuth2Scope.SEARCH);
+ String result = searchService.search(jsonld, ctx.getUsername(),
+ headers);
+ return Response.ok(result).build();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ }
+
+ /** Performs for the given query
+ *
+ * @param securityContext
+ * @param request
+ * @param headers
+ * @param locale
+ * @param q
+ * query
+ * @param ql
+ * query language
+ * @param v
+ * query language version
+ * @param ctx
+ * result context
+ * @param cutoff
+ * determines to limit search results to one page only
+ * or not (default false)
+ * @param pageLength
+ * the number of results should be included in a page
+ * @param pageIndex
+ * @param pageInteger page number
+ * @param fields
+ * metadata fields to be included, separated by comma
+ * @param pipes
+ * external plugins for additional processing,
+ * separated by comma
+ * @param accessRewriteDisabled
+ * determine if access rewrite should be disabled
+ * (default false)
+ * @param cq
+ * corpus query defining a virtual corpus
+ * @param engine
+ * @return search results in JSON
+ */
+ @GET
+ @Path("{version}/search")
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ @SearchResourceFilters
+ public Response searchGet (@Context SecurityContext securityContext,
+ @Context HttpServletRequest request,
+ @Context HttpHeaders headers, @Context Locale locale,
+ @QueryParam("q") String q, @QueryParam("ql") String ql,
+ @QueryParam("v") String v, @QueryParam("context") String ctx,
+ @QueryParam("cutoff") Boolean cutoff,
+ @QueryParam("count") Integer pageLength,
+ @QueryParam("offset") Integer pageIndex,
+ @QueryParam("page") Integer pageInteger,
+ @QueryParam("fields") String fields,
+ @QueryParam("pipes") String pipes,
+ @QueryParam("access-rewrite-disabled") boolean accessRewriteDisabled,
+ @QueryParam("show-tokens") boolean showTokens,
+ @DefaultValue("true") @QueryParam("show-snippet") boolean showSnippet,
+ @QueryParam("cq") List<String> cq,
+ @QueryParam("engine") String engine) {
+
+ TokenContext context =
+ (TokenContext) securityContext.getUserPrincipal();
+
+ String result;
+ try {
+ scopeService.verifyScope(context, OAuth2Scope.SEARCH);
+ result = searchService.search(engine, context.getUsername(),
+ headers, q, ql, v, cq, fields, pipes, pageIndex,
+ pageInteger, ctx, pageLength, cutoff,
+ accessRewriteDisabled, showTokens, showSnippet);
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+
+ return Response.ok(result).build();
+ }
+
+ // EM: legacy support
+ @Deprecated
+ @GET
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ @Path("{version}/corpus/{corpusId}/{docId}/{textId}/{matchId}/matchInfo")
+ @SearchResourceFilters
+ public Response getMatchInfo (@Context SecurityContext ctx,
+ @Context HttpHeaders headers, @Context Locale locale,
+ @PathParam("corpusId") String corpusId,
+ @PathParam("docId") String docId,
+ @PathParam("textId") String textId,
+ @PathParam("matchId") String matchId,
+ @QueryParam("foundry") Set<String> foundries,
+ @QueryParam("layer") Set<String> layers,
+ @QueryParam("spans") Boolean spans,
+ // Highlights may also be a list of valid highlight classes
+ @QueryParam("hls") Boolean highlights) throws KustvaktException {
+
+ return retrieveMatchInfo(ctx, headers, locale, corpusId, docId, textId,
+ matchId, foundries, layers, spans, "true", "false",
+ "sentence", highlights);
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ @Path("{version}/corpus/{corpusId}/{docId}/{textId}/{matchId}")
+ @SearchResourceFilters
+ public Response retrieveMatchInfo (@Context SecurityContext ctx,
+ @Context HttpHeaders headers, @Context Locale locale,
+ @PathParam("corpusId") String corpusId,
+ @PathParam("docId") String docId,
+ @PathParam("textId") String textId,
+ @PathParam("matchId") String matchId,
+ @QueryParam("foundry") Set<String> foundries,
+ @QueryParam("layer") Set<String> layers,
+ @QueryParam("spans") Boolean spans,
+ @DefaultValue("true") @QueryParam("show-snippet") String snippetStr,
+ @DefaultValue("false") @QueryParam("show-tokens") String tokensStr,
+ @QueryParam("expand") String expansion,
+ // Highlights may also be a list of valid highlight classes
+ @QueryParam("hls") Boolean highlights) throws KustvaktException {
+
+ TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
+ try {
+ scopeService.verifyScope(tokenContext, OAuth2Scope.MATCH_INFO);
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+
+ Boolean expandToSentence = true;
+ if (expansion != null
+ && (expansion.equals("false") || expansion.equals("null"))) {
+ expandToSentence = false;
+ }
+ spans = spans != null ? spans : false;
+ Boolean snippet = true;
+ Boolean tokens = false;
+ if (snippetStr != null
+ && (snippetStr.equals("false") || snippetStr.equals("null")))
+ snippet = false;
+
+ if (tokensStr != null && (tokensStr.equals("true")
+ || tokensStr.equals("1") || tokensStr.equals("yes")))
+ tokens = true;
+
+ highlights = highlights != null ? highlights : false;
+ if (layers == null || layers.isEmpty())
+ layers = new HashSet<>();
+
+ try {
+ String results = searchService.retrieveMatchInfo(corpusId, docId,
+ textId, matchId, true, foundries,
+ tokenContext.getUsername(), headers, layers, spans, snippet,
+ tokens, expandToSentence, highlights);
+ return Response.ok(results).build();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+
+ }
+
+ /*
+ * Returns the meta data fields of a certain document
+ */
+ // This is currently identical to LiteService#getMeta(),
+ // but may need auth code to work following policies
+ @GET
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ @Path("{version}/corpus/{corpusId}/{docId}/{textId}")
+ public Response getMetadata (@PathParam("corpusId") String corpusId,
+ @PathParam("docId") String docId,
+ @PathParam("textId") String textId,
+ @QueryParam("fields") String fields,
+ @Context SecurityContext ctx,
+ @Context HttpHeaders headers
+ ) throws KustvaktException {
+ TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
+ try {
+ String results = searchService.retrieveDocMetadata(corpusId, docId,
+ textId, fields, tokenContext.getUsername(), headers);
+ return Response.ok(results).build();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ }
+
+// EM: This web service requires Karang and is DISABLED.
+// @POST
+// @Path("{version}/colloc")
+// @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public Response getCollocationBase (@QueryParam("q") String query) {
+ String result;
+ try {
+ result = searchService.getCollocationBase(query);
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ return Response.ok(result).build();
+ }
+
+ // @GET
+ // @Path("colloc")
+ // public Response getCollocationsAll(@Context SecurityContext
+ // ctx,
+ // @Context Locale locale, @QueryParam("props") String properties,
+ // @QueryParam("sfskip") Integer sfs,
+ // @QueryParam("sflimit") Integer limit, @QueryParam("q") String
+ // query,
+ // @QueryParam("ql") String ql, @QueryParam("context") Integer
+ // context,
+ // @QueryParam("foundry") String foundry,
+ // @QueryParam("paths") Boolean wPaths) {
+ // TokenContext tokenContext = (TokenContext)
+ // ctx.getUserPrincipal();
+ // ColloQuery.ColloQueryBuilder builder;
+ // KoralCollectionQueryBuilder cquery = new
+ // KoralCollectionQueryBuilder();
+ // String result;
+ // try {
+ // User user = controller.getUser(tokenContext.getUsername());
+ // Set<VirtualCollection> resources = ResourceFinder
+ // .search(user, VirtualCollection.class);
+ // for (KustvaktResource c : resources)
+ // cquery.addResource(((VirtualCollection) c).getQuery());
+ //
+ // builder = functions
+ // .buildCollocations(query, ql, properties, context, limit,
+ // sfs, foundry, new ArrayList<Dependency>(), wPaths,
+ // cquery);
+ //
+ // result = graphDBhandler
+ // .getResponse("distCollo", "q", builder.build().toJSON());
+ // }catch (KustvaktException e) {
+ // throw KustvaktResponseHandler.throwit(e);
+ // }catch (JsonProcessingException e) {
+ // throw
+ // KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
+ // }
+ // return Response.ok(result).build();
+ // }
+
+ // /**
+ // * @param locale
+ // * @param properties a json object string containing field, op
+ // and value
+ // for the query
+ // * @param query
+ // * @param context
+ // * @return
+ // */
+ // @GET
+ // @Path("{type}/{id}/colloc")
+ // public Response getCollocations(@Context SecurityContext ctx,
+ // @Context Locale locale, @QueryParam("props") String properties,
+ // @QueryParam("sfskip") Integer sfs,
+ // @QueryParam("sflimit") Integer limit, @QueryParam("q") String
+ // query,
+ // @QueryParam("ql") String ql, @QueryParam("context") Integer
+ // context,
+ // @QueryParam("foundry") String foundry,
+ // @QueryParam("paths") Boolean wPaths, @PathParam("id") String
+ // id,
+ // @PathParam("type") String type) {
+ // ColloQuery.ColloQueryBuilder builder;
+ // type = StringUtils.normalize(type);
+ // id = StringUtils.decodeHTML(id);
+ // TokenContext tokenContext = (TokenContext)
+ // ctx.getUserPrincipal();
+ // String result;
+ // try {
+ // KoralCollectionQueryBuilder cquery = new
+ // KoralCollectionQueryBuilder();
+ // try {
+ // User user = controller.getUser(tokenContext.getUsername());
+ //
+ // KustvaktResource resource = this.resourceHandler
+ // .findbyStrId(id, user, type);
+ //
+ // if (resource instanceof VirtualCollection)
+ // cquery.addResource(
+ // ((VirtualCollection) resource).getQuery());
+ // else if (resource instanceof Corpus)
+ // cquery.addMetaFilter("corpusID",
+ // resource.getPersistentID());
+ // else
+ // throw KustvaktResponseHandler
+ // .throwit(StatusCodes.ILLEGAL_ARGUMENT,
+ // "Type parameter not supported", type);
+ //
+ // }catch (KustvaktException e) {
+ // throw KustvaktResponseHandler.throwit(e);
+ // }catch (NumberFormatException ex) {
+ // throw KustvaktResponseHandler
+ // .throwit(StatusCodes.ILLEGAL_ARGUMENT);
+ // }
+ //
+ // builder = functions
+ // .buildCollocations(query, ql, properties, context, limit,
+ // sfs, foundry, new ArrayList<Dependency>(), wPaths,
+ // cquery);
+ //
+ // result = graphDBhandler
+ // .getResponse("distCollo", "q", builder.build().toJSON());
+ //
+ // }catch (JsonProcessingException e) {
+ // throw
+ // KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
+ // }catch (KustvaktException e) {
+ // throw KustvaktResponseHandler.throwit(e);
+ // }
+ //
+ // return Response.ok(result).build();
+ // }
+
+}
diff --git a/core/src/main/java/de/ids_mannheim/korap/core/web/controller/StatisticController.java b/core/src/main/java/de/ids_mannheim/korap/core/web/controller/StatisticController.java
new file mode 100644
index 0000000..c053d45
--- /dev/null
+++ b/core/src/main/java/de/ids_mannheim/korap/core/web/controller/StatisticController.java
@@ -0,0 +1,111 @@
+package de.ids_mannheim.korap.core.web.controller;
+
+import java.util.List;
+import java.util.Locale;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import de.ids_mannheim.korap.web.utils.ResourceFilters;
+import de.ids_mannheim.korap.core.service.StatisticService;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.web.CoreResponseHandler;
+import de.ids_mannheim.korap.web.filter.APIVersionFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+
+/**
+ * Web services related to statistics
+ *
+ * @author hanl
+ * @author margaretha
+ *
+ * @date 08/11/2017
+ *
+ */
+@Controller
+@Path("{version}/statistics/")
+@ResourceFilters({ APIVersionFilter.class, PiwikFilter.class })
+@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+public class StatisticController {
+
+ private static final boolean DEBUG = false;
+ private static Logger jlog =
+ LogManager.getLogger(StatisticController.class);
+ @Autowired
+ private CoreResponseHandler kustvaktResponseHandler;
+ @Autowired
+ private StatisticService service;
+
+ /**
+ * Returns statistics of the virtual corpus defined by the given
+ * corpusQuery parameter.
+ *
+ * @param context
+ * SecurityContext
+ * @param locale
+ * Locale
+ * @param cq
+ * a collection query specifying a virtual corpus
+ * @param corpusQuery
+ * (DEPRECATED) a collection query specifying a virtual
+ * corpus
+ * @return statistics of the virtual corpus defined by the given
+ * corpusQuery parameter.
+ */
+ @GET
+ public Response getStatistics (@Context SecurityContext context,
+ @Context Locale locale, @QueryParam("cq") List<String> cq,
+ @QueryParam("corpusQuery") List<String> corpusQuery) {
+
+ String stats;
+ boolean isDeprecated = false;
+ try {
+ if (cq.isEmpty() && corpusQuery != null && !corpusQuery.isEmpty()) {
+ isDeprecated = true;
+ cq = corpusQuery;
+ }
+ stats = service.retrieveStatisticsForCorpusQuery(cq, isDeprecated);
+ if (DEBUG) {
+ jlog.debug("Stats: " + stats);
+ }
+
+ return Response
+ .ok(stats)
+ .header("X-Index-Revision", service.getIndexFingerprint())
+ .build();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public Response getStatisticsFromKoralQuery (
+ @Context SecurityContext context, @Context Locale locale,
+ String koralQuery) {
+ try {
+ String stats = service.retrieveStatisticsForKoralQuery(koralQuery);
+ return Response
+ .ok(stats)
+ .header("X-Index-Revision", service.getIndexFingerprint())
+ .build();
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ }
+}